rpms/kernel/FC-4 0071-8139cp-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0072-8139too-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0073-b44-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0074-e1000-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0075-e100-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0076-forcedeth-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0077-ixgb-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0078-ne2k-pci-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0079-pcnet32-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0080-r8169-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0081-skge-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0082-sundance-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0083-via-rhine-support-ETHTOOL_GPERMADDR.txt, NONE, 1.1.2.1 0085-drivers-net-fix-up-schedule_timeout-usage.txt, NONE, 1.1.2.1 0086-Replace-drivers-net-wan-custom-ctype-macros-with-standard-ones.txt, NONE, 1.1.2.1 0087-drivers-net-wan-possible-cleanups.txt, NONE, 1.1.2.1 0088-lne390-bogus-casts.txt, NONE, 1.1.2.1 0! 089-C99-initializers-in-ray_cs.c.txt, NONE, 1.1.2.1 0090-mii-Add-test-for-GigE-support.txt, NONE, 1.1.2.1 0099-pcnet32-set_ringparam-implementation.txt, NONE, 1.1.2.1 0100-pcnet32-set-min-ring-size-to-4.txt, NONE, 1.1.2.1 0101-orinoco-Remove-conditionals-that-are-useless-in-the-kernel-drivers.txt, NONE, 1.1.2.1 0102-orinoco-Don-t-include-net-ieee80211.h-twice.txt, NONE, 1.1.2.1 0103-orinoco-Update-PCMCIA-ID-s.txt, NONE, 1.1.2.1 0112-Updated-ipw2200-to-compile-with-ieee80211-abg_ture-to-abg_true-change.txt, NONE, 1.1.2.1 0161-ieee80211-Updated-ipw2100-to-be-compatible-with-ieee80211_hdr-changes.txt, NONE, 1.1.2.1 0162-ieee80211-Updated-ipw2100-to-be-compatible-with-ieee80211-s-hard_start_xmit-change.txt, NONE, 1.1.2.1 0163-ieee80211-Updated-ipw2200-to-be-compatible-with-ieee80211_hdr-changes.txt, NONE, 1.1.2.1 0164-ieee80211-Updated-ipw2200-to-be-compatible-with-ieee80211-s-hard_start_xmit-change.txt, NONE, 1.1.2.1 0165-ieee80211-Updated-atmel-to-be-compatible-with-ieee80211_hdr-changes.txt, NONE, 1.! 1.2.1 0186-ieee80211-Updated-hostap-to-be-compatible-with-ieee! 80211_hd

fedora-cvs-commits at redhat.com fedora-cvs-commits at redhat.com
Thu Nov 10 21:24:55 UTC 2005


Author: linville

Update of /cvs/dist/rpms/kernel/FC-4
In directory cvs.devel.redhat.com:/tmp/cvs-serv24096

Added Files:
      Tag: private-linville-netdev-fc4-1-branch
	0071-8139cp-support-ETHTOOL_GPERMADDR.txt 
	0072-8139too-support-ETHTOOL_GPERMADDR.txt 
	0073-b44-support-ETHTOOL_GPERMADDR.txt 
	0074-e1000-support-ETHTOOL_GPERMADDR.txt 
	0075-e100-support-ETHTOOL_GPERMADDR.txt 
	0076-forcedeth-support-ETHTOOL_GPERMADDR.txt 
	0077-ixgb-support-ETHTOOL_GPERMADDR.txt 
	0078-ne2k-pci-support-ETHTOOL_GPERMADDR.txt 
	0079-pcnet32-support-ETHTOOL_GPERMADDR.txt 
	0080-r8169-support-ETHTOOL_GPERMADDR.txt 
	0081-skge-support-ETHTOOL_GPERMADDR.txt 
	0082-sundance-support-ETHTOOL_GPERMADDR.txt 
	0083-via-rhine-support-ETHTOOL_GPERMADDR.txt 
	0085-drivers-net-fix-up-schedule_timeout-usage.txt 
	0086-Replace-drivers-net-wan-custom-ctype-macros-with-standard-ones.txt 
	0087-drivers-net-wan-possible-cleanups.txt 
	0088-lne390-bogus-casts.txt 
	0089-C99-initializers-in-ray_cs.c.txt 
	0090-mii-Add-test-for-GigE-support.txt 
	0099-pcnet32-set_ringparam-implementation.txt 
	0100-pcnet32-set-min-ring-size-to-4.txt 
	0101-orinoco-Remove-conditionals-that-are-useless-in-the-kernel-drivers.txt 
	0102-orinoco-Don-t-include-net-ieee80211.h-twice.txt 
	0103-orinoco-Update-PCMCIA-ID-s.txt 
	0112-Updated-ipw2200-to-compile-with-ieee80211-abg_ture-to-abg_true-change.txt 
	0161-ieee80211-Updated-ipw2100-to-be-compatible-with-ieee80211_hdr-changes.txt 
	0162-ieee80211-Updated-ipw2100-to-be-compatible-with-ieee80211-s-hard_start_xmit-change.txt 
	0163-ieee80211-Updated-ipw2200-to-be-compatible-with-ieee80211_hdr-changes.txt 
	0164-ieee80211-Updated-ipw2200-to-be-compatible-with-ieee80211-s-hard_start_xmit-change.txt 
	0165-ieee80211-Updated-atmel-to-be-compatible-with-ieee80211_hdr-changes.txt 
	0186-ieee80211-Updated-hostap-to-be-compatible-with-ieee80211_hdr-changes.txt 
	0187-ieee80211-Updated-hostap-to-be-compatible-with-extra_prefix_len-changes.txt 
	0189-forcedeth-add-hardware-tx-checksumming.txt 
	0198-ieee80211-update-orinoco-wl3501-drivers-for-latest-struct-naming.txt 
	0211-orinoco-Remove-inneeded-system-includes.txt 
	0212-orinoco-Make-nortel_pci_hw_init-static.txt 
	0213-orinoco-Fix-memory-leak-and-unneeded-unlock-in-orinoco_join_ap.txt 
	0214-orinoco-orinoco_send_wevents-could-return-without-unlocking.txt 
	0215-orinoco-Remove-unneeded-forward-declarations.txt 
	0216-orinoco-Annotate-endianess-of-variables-and-structure-members.txt 
	0217-orinoco-Read-only-needed-data-in-__orinoco_ev_txexc.txt 
	0218-orinoco-Bump-version-to-0.15rc3.txt 
	0263-hostap-Fix-pci_driver-name-for-hostap_plx-and-hostap_pci.txt 
	0264-hostap-Add-support-for-WE-19.txt 
	0265-hostap-Use-GFP_ATOMIC-to-get-rid-of-weird-might_sleep-issue.txt 
	0266-hostap-Remove-iwe_stream_add_event-kludge.txt 
	0267-Remove-WIRELESS_EXT-ifdefs-from-several-wireless-drivers.txt 
	0268-wireless-airo-remove-needed-dma_addr_t-obfuscation.txt 
	0345-hostap-Remove-hw-specific-dev_open-close-handlers.txt 
	0346-hostap-Fix-hostap_pci-build-with-PRISM2_IO_DEBUG.txt 
	0347-hostap-Do-not-free-local-hw_priv-before-unregistering-netdev.txt 
	0348-hostap-Unregister-netdevs-before-freeing-local-data.txt 
	0355-S2io-MSI-MSI-X-support-runtime-configurable.txt 
	0356-e1000-Support-for-82571-and-82572-controllers.txt 
	0357-e1000-multi-queue-defines-modification-to-data-structures.txt 
	0358-e1000-implementation-of-the-multi-queue-feature.txt 
	0359-e1000-Enable-custom-configuration-bits-for-82571-2-controllers.txt 
	0360-e1000-Fixes-for-packet-split-related-issues.txt 
	0361-e1000-Added-msleep_interruptible-delay.txt 
	0362-e1000-Flush-shadow-RAM.txt 0363-e1000-fix-warnings.txt 
	0364-AX.25-Delete-debug-printk-from-mkiss-driver.txt 
	0365-AX.25-Convert-mkiss.c-to-DEFINE_RWLOCK.txt 
	0366-airo-fix-resume.txt 
	0367-s2io-change-strncpy-length-arg-to-use-size-of-target.txt 
	0368-netdrvr-s2io-Add-a-MODULE_VERSION-entry.txt 
	0369-bonding-replicate-IGMP-traffic-in-activebackup-mode.txt 
	0371-wireless-ipw2200-remove-redundant-return-statement.txt 
	0534-S2io-Offline-diagnostics-fixes.txt 
	0535-rcu-in-bpqether-driver.txt 
	0536-SMACK-support-for-mkiss.txt 
	0537-Initialize-the-.owner-field-the-tty_ldisc-structure.txt 
	0565-sb1250-mac-Check-the-actual-setting-for-reporting-hw-checksumming.txt 
	0566-sb1250-mac-Ensure-16-byte-alignment-of-the-descriptor-ring.txt 
	0567-au1000_eth-Misc-Au1000-net-driver-fixes.txt 
	0568-de2104x-Resurrect-Cobalt-support-for-2.6.txt 
	0569-sgiseeq-Fix-resource-handling.txt 
	0570-sgiseeq-Configure-PIO-and-DMA-timing-requests.txt 
	0571-declance-Convert-to-irqreturn_t.txt 
	0572-declance-Fix-mapping-of-device.txt 
	0573-declance-Deal-with-the-bloody-KSEG-vs-CKSEG-horror.txt 
	0574-declance-Use-physical-addresses-at-the-interface-level.txt 
	0575-ne-Support-for-RBHMA4500-eval-board.txt 
	0577-e1000_intr-build-fix.txt 0578-s2io-build-fix.txt 
	0580-via-rhine-change-mdelay-to-msleep-and-remove-from-ISR-path.txt 
	0581-epic100-fix-counting-of-work_done-in-epic_poll.txt 
	0585-b44-alternate-allocation-option-for-DMA-descriptors.txt 
	0586-orinoco-remove-redundance-skb-length-check-before-padding.txt 
	0587-sundance-remove-if-1-.-block-in-sundance_probe1.txt 
	0588-sundance-expand-reset-mask.txt 0589-e1000-build-fix.txt 
	0619-sb1250-mac-Get-rid-of-all-the-funny-SBMAC_WRITECSR-and-SBMAC_READCSR-macros.txt 
	0620-sb1250-mac-Whitespace-cleanup.txt 
	0633-sundance-include-MII-address-0-in-PHY-probe.txt 
	0634-e1000-Driver-version-white-space-comments-device-id-other.txt 
	0640-sb1250-mac-PHY-probing-fixes.txt 
	0663-PARISC-Change-the-driver-names-so-sys-bus-parisc-drivers-looks-better.txt 
	0664-PARISC-Convert-parisc_device-to-use-struct-resource-for-hpa.txt 
	0702-PARISC-Add-NETPOLL-support-to-lasi_82596.txt 
	0773-netdrvr-forcedeth-scatter-gather-and-segmentation-offload-support.txt 
	0940-gfp_t-drivers-net.txt 
	0945-ARM-2919-1-CS8900A-ethernet-driver-modifications-for-the-Comdial-MP1000.txt 
	1012-DRIVER-MODEL-Get-rid-of-the-obsolete-tri-level-suspend-resume-callbacks.txt 
	1038-tg3-add-5714-5715-support.txt 
	1039-tg3-fix-ASF-heartbeat.txt 
	1040-tg3-update-version-and-minor-fixes.txt 
	1041-ibmveth-fix-bonding.txt 
	1042-ibmveth-fix-buffer-pool-management.txt 
	1043-ibmveth-fix-buffer-replenishing.txt 
	1044-ibmveth-lockless-TX.txt 
	1045-ibmveth-fix-failed-addbuf.txt 
	1046-pcnet_cs-fix-mii-init-code-for-older-DL10019-based-cards.txt 
	1048-s2io-kconfig-help-fix.txt 
	1049-b44-reports-wrong-advertised-flags.txt 
	1050-sis190.c-fix-multicast-MAC-filter.txt 
	1051-smc91x-shut-down-power-after-probing.txt 
	1053-starfire-free_irq-on-error-path-of-netdev_open.txt 
	1056-netdrvr-b44-include-linux-dma-mapping.h-to-eliminate-warning.txt 
	1057-sundance-fix-DFE-580TX-Tx-Underrun.txt 
	1061-sis900-come-alive-after-temporary-memory-shortage.txt 
	1062-drivers-net-Remove-pointless-checks-for-NULL-prior-to-calling-kfree.txt 
	1064-netdrvr-ne2k-pci-based-card-does-not-support-bus-mastering.txt 
	1065-ipw2200-Missing-kmalloc-check.txt 
	1182-e1000-remove-warning-about-e1000_suspend.txt 
	1183-eepro.c-module_param_array-cleanup.txt 
	1184-b44-fix-suspend-resume.txt 
	1185-e1000-use-vmalloc_node.txt 
	1186-revert-orinoco-Information-leakage-due-to-incorrect-padding.txt 
	1187-Better-fixup-for-the-orinoco-driver.txt 
	1188-e1000-Fixes-e1000_suspend-warning-when-CONFIG_PM-is-not-enabled.txt 
	1306-Add-modalias-for-pmac-network-drivers.txt 
	1310-mv643xx_eth_showsram-Added-information-message-when-using-the-SRAM.txt 
	1371-s2io-iomem-annotations.txt 
	1385-drivers-net-tg3-Use-the-DMA_-32-64-BIT_MASK-constants.txt 
	1387-prism54-Free-skb-after-disabling-interrupts.txt 
	1736-fec_8xx-Remove-dependency-on-NETTA-NETPHONE.txt 
	1737-fec_8xx-Add-support-for-Intel-PHY-LX971.txt 
	1902-m32r-SMC91x-driver-update.txt 
	1923-remove-some-more-check_region-stuff.txt 
	1943-Typo-fix-dot-after-newline-in-printk-strings.txt 
	2008-sparse-cleanups-NULL-pointers-C99-struct-init.txt 
	2207-ibmveth-fix-panic-in-initial-replenish-cycle.txt 
	2409-drivers-net-wireless-airo.c-unsigned-comparason.txt 
	2410-S2io-Multi-buffer-mode-support.txt 
	2412-pcnet32-show-name-of-failing-device.txt 
	2413-pcnet32-AT2700-2701-and-Bugzilla-2699-4551.txt 
	2414-pcnet32-Prevent-hang-with-79c976.txt 
	2415-phy-address-mask-support-for-generic-phy-layer.txt 
	2443-DRIVER-MODEL-Fix-depca.txt 
	2444-DRIVER-MODEL-Fix-jazzsonic.txt 
	2445-DRIVER-MODEL-Fix-macsonic.txt 
	2455-drivers-net-ixgb-make-some-code-static.txt 
	2456-drivers-net-e1000-possible-cleanups.txt 
	2457-drivers-net-hamradio-dmascc.c-remove-dmascc_setup.txt 
	2458-prism54-Remove-redundant-assignment.txt 
	2459-bnx2-add-5708-support.txt 
	2460-bnx2-update-firmware-for-5708.txt 
	2461-bnx2-update-nvram-code-for-5708.txt 
	2462-bnx2-update-firmware-handshake-for-5708.txt 
	2463-bnx2-refine-bnx2_poll.txt 
	2464-bnx2-update-version-and-minor-fixes.txt 
	2468-netdrvr-fac_8xx-build-fix.txt 
	2469-netdrvr-s2io-warning-fixes.txt 
	2576-b44-b44_start_xmit-returns-with-a-lock-held-when-it-fails-allocating.txt 
	2579-b44-s-spin_lock_irqsave-spin_lock-in-b44_interrupt.txt 
	2580-b44-late-request_irq-in-b44_open.txt 
	2612-3c59x-convert-to-use-of-pci_iomap-API.txt 
	2613-3c59x-cleanup-of-mdio_read-routines-to-use-MII_-macros.txt 
	2614-3c59x-avoid-blindly-reading-link-status-twice.txt 
	2615-3c59x-bounds-checking-for-hw_checksums.txt 
	2616-3c59x-cleanup-init-of-module-parameter-arrays.txt 
	2617-3c59x-fix-some-grammar-in-module-parameter-descriptions.txt 
	2618-3c59x-support-ETHTOOL_GPERMADDR.txt 
	2619-3c59x-correct-rx_dropped-counting.txt 
	2620-3c59x-enable-use-of-memory-mapped-PCI-I-O.txt 
	2621-3c59x-don-t-enable-scatter-gather-w-o-checksum-support.txt 
	2652-uml-fix-UML-network-driver-endianness-bugs.txt 
	2858-m68knommu-FEC-ethernet-header-support-for-the-ColdFire-5208.txt 
	2859-m68knommu-FEC-ethernet-support-for-the-ColdFire-5208.txt 
	2910-Ran-scripts-Lindent-on-drivers-net-wireless-ipw2-1-2-00.-c-h.txt 
	2911-IPW_DEBUG-has-already-included-DRV_NAME-remove-double-prefix-print.txt 
	2912-Catch-ipw2200-up-to-equivelancy-with-v1.0.1.txt 
	2913-Catch-ipw2200-up-to-equivelancy-with-v1.0.2.txt 
	2914-Catch-ipw2200-up-to-equivelancy-with-v1.0.3.txt 
	2915-Catch-ipw2200-up-to-equivelancy-with-v1.0.4.txt 
	2916-Catch-ipw2100-up-to-equivelancy-with-v1.1.1.txt 
	2917-Fixed-WEP-on-ipw2100-priv-sec-was-being-used-instead-of.txt 
	2918-Bug-339-Fix-ipw2100-iwconfig-set-get-txpower.txt 
	2919-Move-code-from-ipw2100_wpa_enable-to-IPW2100_PARAM_DROP_UNENCRYPTED-to.txt 
	2920-Catch-ipw2200-up-to-equivelancy-with-v1.0.5.txt 
	2921-Fix-hardware-encryption-both-WEP-and-AES-doesn-t-work-with-fragmentation.txt 
	2922-Fix-is_duplicate_packet-bug-for-fragmentation-number-setting.txt 
	2923-bug-667-Fix-the-notorious-No-space-for-Tx-bug.txt 
	2924-Bug-637-Set-tx-power-for-A-band.txt 
	2925-Changed-default-of-missed-beacons-to-miss-before-disassociation-to-24.txt 
	2926-Updated-to-support-ieee80211-callback-to-is_queue_full-for-802.11e.txt 
	2927-Fixed-some-compiler-issues-if-CONFIG_IPW2200_QOS-is-enabled.txt 
	2928-Added-more-useful-geography-encoding-so-people-s-experience-with.txt 
	2929-Workaround-kernel-BUG_ON-panic-caused-by-unexpected-duplicate-packets.txt 
	2930-Disable-host-fragmentation-in-open-mode-since-IPW2200-2915-hardware.txt 
	2931-Bug-792-Fix-WPA-PSK-AES-both-for-Dipw-and-Dwext.txt 
	2932-Fixes-the-ad-hoc-network-WEP-key-list-issue.txt 
	2933-Bug-701-Fix-a-misuse-of-ieee-mode-with-ieee-iw_mode.txt 
	2934-Fix-ipw_wx_get_txpow-shows-wrong-disabled-value.txt 
	2935-Fix-firmware-error-when-setting-tx_power.txt 
	2936-Modified-ipw_config-and-STATUS_INIT-setting-to-correct-race-condition.txt 
	2937-Switched-firmware-error-dumping-so-that-it-will-capture-a-log-available.txt 
	2938-Changed-all-of-the-ipw_send_cmd-calls-to-return-any-ipw_send_cmd-error.txt 
	2939-Added-cmdlog-in-non-debug-systems.txt 
	2940-Migrated-some-of-the-channel-verification-code-back-into-the-driver-to.txt 
	2941-Updated-ipw2200-to-use-the-new-ieee80211-callbacks.txt 
	2942-Added-wait_state-wakeup-on-scan-completion.txt 
	2943-Bug-455-Fix-frequent-channel-change-generates-firmware-fatal-error.txt 
	2944-Bug-760-Fix-setting-WEP-key-in-monitor-mode-causes-IV-lost.txt 
	2945-Don-t-set-hardware-WEP-if-we-are-actually-using-TKIP-AES.txt 
	2946-Make-all-the-places-the-firmware-fails-to-load-showerrors-in-decimal.txt 
	2947-Adds-radiotap-support-to-ipw2200-in-monitor-mode.txt 
	2948-Fixed-is_network_packet-to-include-checking-for-broadcast-packets.txt 
	2949-Mixed-PTK-GTK-CCMP-TKIP-support.txt 
	2950-Card-with-WEP-enabled-and-using-shared-key-auth-will-have-firmware.txt 
	2951-Fixed-problem-with-get_cmd_string-not-existing-if-CONFIG_IPW_DEBUG-disabled.txt 
	2952-Removed-PF_SYNCTHREAD-legacy.txt 
	2953-Fixes-problem-with-WEP-not-working-association-succeeds-but-no-Tx-Rx.txt 
	2954-Fix-bug-771-Too-many-8-bytes-recieved-when-using-AES-hwcrypto.txt 
	2955-Fixes-WEP-firmware-error-condition.txt 
	2956-Updated-driver-version-stamps-for-ipw2100-1.1.3-and-ipw2200-1.0.7.txt 
	2957-Pulled-out-a-stray-KERNEL_VERSION-check-around-the-suspend-handler.txt 
	2958-Fix-Driver-using-old-proc-net-wireless-support-please-fix-driver-message.txt 
	2959-Removed-legacy-WIRELESS_EXT-checks-from-ipw2200.c.txt 
	2960-Fixes-missed-beacon-logic-in-relation-to-on-network-AP-roaming.txt 
	2961-Removed-warning-about-TKIP-not-being-configured-if-countermeasures-are.txt 
	2962-Added-channel-support-for-ipw2200-cards-identified-as-ZZR.txt 
	2963-Fixed-problem-with-not-being-able-to-send-broadcast-packets.txt 
	2964-Fixed-parameter-reordering-in-firmware-log-routine.txt 
	2965-Updated-firmware-version-stamp-to-2.4-from-2.3-so-it-will-use-the-latest-firmware.txt 
	2966-Update-version-ipw2200-stamp-to-1.0.8.txt 
	3005-bonding-fix-feature-consolidation.txt 
	3007-drivers-net-s2io.c-make-functions-static.txt 
	3008-prism54-Unused-variable-extraneous-udelay.txt 
	3009-prism54-Transmit-stats-updated-in-wrong-place.txt 
	3010-Fix-sparse-warning-in-e100-driver.txt 
	3011-atmel-memset-correct-range.txt 
	3028-PPP-handle-misaligned-accesses.txt 
	3030-IRDA-donauboe-locking-fix.txt 
	3053-SERIAL-IOC3-Update-8250-driver-bits.txt 
	3055-skge-clear-PCI-PHY-COMA-mode-on-boot.txt 
	3056-skge-use-kzalloc.txt 3057-skge-add-mii-ioctl-support.txt 
	3058-skge-goto-low-power-mode-on-shutdown.txt 
	3059-skge-use-prefetch-on-receive.txt 
	3060-skge-spelling-fixes.txt 
	3061-skge-increase-version-number.txt 
	3062-wireless-ipw2100-kill-unused-var-warnings-for-debug-disabled-code.txt 
	3064-b44-replace-B44_FLAG_INIT_COMPLETE-with-netif_running.txt 
	3065-b44-race-on-device-closing.txt 
	3066-b44-increase-version-number.txt 
	3067-cris-v10-eth-use-ethtool_ops.txt 
	3069-uml_net-use-ethtool_ops.txt 
	3072-dgrs-fix-warnings-when-CONFIG_ISA-and-CONFIG_PCI-are-not-enabled.txt 
	3073-IOC-And-don-t-mark-the-things-as-broken-Cowboy.txt 
Log Message:



--- NEW FILE 0071-8139cp-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] 8139cp: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536534 -0400

Add support for ETHTOOL_GPERMADDR to 8139cp.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/8139cp.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: 511a3a60a0828df91658c50a4bffce481ced2454
bb0ce608a3386268bd76ee6642a4cc8e6818a29b
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index 34b80de..ebc20d9 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1575,6 +1575,7 @@ static struct ethtool_ops cp_ethtool_ops
 	.set_wol		= cp_set_wol,
 	.get_strings		= cp_get_strings,
 	.get_ethtool_stats	= cp_get_ethtool_stats,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
 
 static int cp_ioctl (struct net_device *dev, struct ifreq *rq, int cmd)
@@ -1773,6 +1774,7 @@ static int cp_init_one (struct pci_dev *
 	for (i = 0; i < 3; i++)
 		((u16 *) (dev->dev_addr))[i] =
 		    le16_to_cpu (read_eeprom (regs, i + 7, addr_len));
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	dev->open = cp_open;
 	dev->stop = cp_close;
---
0.99.8.GIT


--- NEW FILE 0072-8139too-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] 8139too: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536535 -0400

Add support for ETHTOOL_GPERMADDR to 8139too.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/8139too.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: 00648bee47898e3ef84448b6e6e30feba1fec2c6
62a720b889a37496d5f36d09875578956745d196
diff --git a/drivers/net/8139too.c b/drivers/net/8139too.c
index 4c2cf7b..76ef6ef 100644
--- a/drivers/net/8139too.c
+++ b/drivers/net/8139too.c
@@ -970,6 +970,7 @@ static int __devinit rtl8139_init_one (s
 	for (i = 0; i < 3; i++)
 		((u16 *) (dev->dev_addr))[i] =
 		    le16_to_cpu (read_eeprom (ioaddr, i + 7, addr_len));
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/* The Rtl8139-specific entries in the device structure. */
 	dev->open = rtl8139_open;
@@ -2465,6 +2466,7 @@ static struct ethtool_ops rtl8139_ethtoo
 	.get_strings		= rtl8139_get_strings,
 	.get_stats_count	= rtl8139_get_stats_count,
 	.get_ethtool_stats	= rtl8139_get_ethtool_stats,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
---
0.99.8.GIT


--- NEW FILE 0073-b44-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] b44: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536535 -0400

Add support for ETHTOOL_GPERMADDR to b44.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: b1d85cf0fd796e7331f86a3dc1509fcd63a9069e
2160de53cc17a40ad07bd38bf52dd0bb72dd5183
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 94939f5..d27e870 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1676,6 +1676,7 @@ static struct ethtool_ops b44_ethtool_op
 	.set_pauseparam		= b44_set_pauseparam,
 	.get_msglevel		= b44_get_msglevel,
 	.set_msglevel		= b44_set_msglevel,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
 
 static int b44_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
@@ -1718,6 +1719,7 @@ static int __devinit b44_get_invariants(
 	bp->dev->dev_addr[3] = eeprom[80];
 	bp->dev->dev_addr[4] = eeprom[83];
 	bp->dev->dev_addr[5] = eeprom[82];
+	memcpy(bp->dev->perm_addr, bp->dev->dev_addr, bp->dev->addr_len);
 
 	bp->phy_addr = eeprom[90] & 0x1f;
 
---
0.99.8.GIT


--- NEW FILE 0074-e1000-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] e1000: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536535 -0400

Add support for ETHTOOL_GPERMADDR to e1000.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_ethtool.c |    1 +
 drivers/net/e1000/e1000_main.c    |    3 ++-
 2 files changed, 3 insertions(+), 1 deletions(-)

applies-to: 398073edc9425debbee57d6bcd844f6291a411e5
9beb0ac17bcfed23feb0a6fac328216568b74bc1
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index f133ff0..8f3a134 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1739,6 +1739,7 @@ struct ethtool_ops e1000_ethtool_ops = {
 	.phys_id                = e1000_phys_id,
 	.get_stats_count        = e1000_get_stats_count,
 	.get_ethtool_stats      = e1000_get_ethtool_stats,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
 
 void e1000_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 7c8a0a2..d02883d 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -614,8 +614,9 @@ e1000_probe(struct pci_dev *pdev,
 	if(e1000_read_mac_addr(&adapter->hw))
 		DPRINTK(PROBE, ERR, "EEPROM Read Error\n");
 	memcpy(netdev->dev_addr, adapter->hw.mac_addr, netdev->addr_len);
+	memcpy(netdev->perm_addr, adapter->hw.mac_addr, netdev->addr_len);
 
-	if(!is_valid_ether_addr(netdev->dev_addr)) {
+	if(!is_valid_ether_addr(netdev->perm_addr)) {
 		DPRINTK(PROBE, ERR, "Invalid MAC Address\n");
 		err = -EIO;
 		goto err_eeprom;
---
0.99.8.GIT


--- NEW FILE 0075-e100-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] e100: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536536 -0400

Add support for ETHTOOL_GPERMADDR to e100.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e100.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

applies-to: f4caff544ae7816cc02857d7b24f9694418eb43c
a92dd9233ad185904daf95d040cf88c3da2d7ef6
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index 25cc20e..1c91830 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -2391,6 +2391,7 @@ static struct ethtool_ops e100_ethtool_o
 	.phys_id		= e100_phys_id,
 	.get_stats_count	= e100_get_stats_count,
 	.get_ethtool_stats	= e100_get_ethtool_stats,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
 
 static int e100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
@@ -2541,7 +2542,8 @@ static int __devinit e100_probe(struct p
 	e100_phy_init(nic);
 
 	memcpy(netdev->dev_addr, nic->eeprom, ETH_ALEN);
-	if(!is_valid_ether_addr(netdev->dev_addr)) {
+	memcpy(netdev->perm_addr, nic->eeprom, ETH_ALEN);
+	if(!is_valid_ether_addr(netdev->perm_addr)) {
 		DPRINTK(PROBE, ERR, "Invalid MAC address from "
 			"EEPROM, aborting.\n");
 		err = -EAGAIN;
---
0.99.8.GIT


--- NEW FILE 0076-forcedeth-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] forcedeth: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536536 -0400

Add support for ETHTOOL_GPERMADDR to forcedeth.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/forcedeth.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

applies-to: c43b02acd9e16948a889d5a4be80358428920945
c704b8566b060695e90ac401833db4b62813ad8a
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index d6eefdb..6e042ec 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -2065,6 +2065,7 @@ static struct ethtool_ops ops = {
 	.get_regs_len = nv_get_regs_len,
 	.get_regs = nv_get_regs,
 	.nway_reset = nv_nway_reset,
+	.get_perm_addr = ethtool_op_get_perm_addr,
 };
 
 static int nv_open(struct net_device *dev)
@@ -2377,8 +2378,9 @@ static int __devinit nv_probe(struct pci
 	dev->dev_addr[3] = (np->orig_mac[0] >> 16) & 0xff;
 	dev->dev_addr[4] = (np->orig_mac[0] >>  8) & 0xff;
 	dev->dev_addr[5] = (np->orig_mac[0] >>  0) & 0xff;
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	if (!is_valid_ether_addr(dev->dev_addr)) {
+	if (!is_valid_ether_addr(dev->perm_addr)) {
 		/*
 		 * Bad mac address. At least one bios sets the mac address
 		 * to 01:23:45:67:89:ab
---
0.99.8.GIT


--- NEW FILE 0077-ixgb-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] ixgb: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536536 -0400

Add support for ETHTOOL_GPERMADDR to ixgb.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/ixgb/ixgb_ethtool.c |    1 +
 drivers/net/ixgb/ixgb_main.c    |    3 ++-
 2 files changed, 3 insertions(+), 1 deletions(-)

applies-to: b9f9c947689f21b4de558e6ef00a1ddf24841a6b
df859c519ef7b72d9be7396443316da87272e8b6
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 9d026ed..319ee4c 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -723,6 +723,7 @@ struct ethtool_ops ixgb_ethtool_ops = {
 	.phys_id = ixgb_phys_id,
 	.get_stats_count = ixgb_get_stats_count,
 	.get_ethtool_stats = ixgb_get_ethtool_stats,
+	.get_perm_addr = ethtool_op_get_perm_addr,
 };
 
 void ixgb_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 5c55537..5015eaf 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -460,8 +460,9 @@ ixgb_probe(struct pci_dev *pdev,
 	}
 
 	ixgb_get_ee_mac_addr(&adapter->hw, netdev->dev_addr);
+	memcpy(netdev->perm_addr, netdev->dev_addr, netdev->addr_len);
 
-	if(!is_valid_ether_addr(netdev->dev_addr)) {
+	if(!is_valid_ether_addr(netdev->perm_addr)) {
 		err = -EIO;
 		goto err_eeprom;
 	}
---
0.99.8.GIT


--- NEW FILE 0078-ne2k-pci-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] ne2k-pci: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536537 -0400

Add support for ETHTOOL_GPERMADDR to ne2k-pci.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/ne2k-pci.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: b4da7767fd6de6881a1339386d04222f7b212f26
78b345890a91dc57fecea8b6792012e0098c058f
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index f1c01ac..e531a4e 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -372,6 +372,7 @@ static int __devinit ne2k_pci_init_one (
 		printk("%2.2X%s", SA_prom[i], i == 5 ? ".\n": ":");
 		dev->dev_addr[i] = SA_prom[i];
 	}
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	return 0;
 
@@ -637,6 +638,7 @@ static struct ethtool_ops ne2k_pci_ethto
 	.get_drvinfo		= ne2k_pci_get_drvinfo,
 	.get_tx_csum		= ethtool_op_get_tx_csum,
 	.get_sg			= ethtool_op_get_sg,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
 
 static void __devexit ne2k_pci_remove_one (struct pci_dev *pdev)
---
0.99.8.GIT


--- NEW FILE 0079-pcnet32-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] pcnet32: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536537 -0400

Add support for ETHTOOL_GPERMADDR to pcnet32.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/pcnet32.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

applies-to: 44ff0982df849e25efb6d5835f8bd1a0dd4bfb4a
db0276b060918fac94c9d216213a31ee02cdd73e
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 113b680..6c3731b 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -957,6 +957,7 @@ static struct ethtool_ops pcnet32_ethtoo
     .phys_id		= pcnet32_phys_id,
     .get_regs_len	= pcnet32_get_regs_len,
     .get_regs		= pcnet32_get_regs,
+    .get_perm_addr	= ethtool_op_get_perm_addr,
 };
 
 /* only probes for non-PCI devices, the rest are handled by
@@ -1185,9 +1186,10 @@ pcnet32_probe1(unsigned long ioaddr, int
 	    memcpy(dev->dev_addr, promaddr, 6);
 	}
     }
+    memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
     /* if the ethernet address is not valid, force to 00:00:00:00:00:00 */
-    if (!is_valid_ether_addr(dev->dev_addr))
+    if (!is_valid_ether_addr(dev->perm_addr))
 	memset(dev->dev_addr, 0, sizeof(dev->dev_addr));
 
     if (pcnet32_debug & NETIF_MSG_PROBE) {
---
0.99.8.GIT


--- NEW FILE 0080-r8169-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] r8169: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536537 -0400

Add support for ETHTOOL_GPERMADDR to r8169.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/r8169.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: 0aff024589d97fbf54cfc8596b23d9df7726323c
6d6525b7f74f9593e647f8c17b1de0f652e1f177
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index f0471d1..cbc60ce 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -1028,6 +1028,7 @@ static struct ethtool_ops rtl8169_ethtoo
 	.get_strings		= rtl8169_get_strings,
 	.get_stats_count	= rtl8169_get_stats_count,
 	.get_ethtool_stats	= rtl8169_get_ethtool_stats,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
 
 static void rtl8169_write_gmii_reg_bit(void __iomem *ioaddr, int reg, int bitnum,
@@ -1512,6 +1513,7 @@ rtl8169_init_one(struct pci_dev *pdev, c
 	/* Get MAC address.  FIXME: read EEPROM */
 	for (i = 0; i < MAC_ADDR_LEN; i++)
 		dev->dev_addr[i] = RTL_R8(MAC0 + i);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	dev->open = rtl8169_open;
 	dev->hard_start_xmit = rtl8169_start_xmit;
---
0.99.8.GIT


--- NEW FILE 0081-skge-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] skge: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536537 -0400

Add support for ETHTOOL_GPERMADDR to skge.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/skge.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: 229b049c611c79b9667b222ed306f662d0fcd2f0
56230d538233ba037eb679b0fc0b218d33b9b8b8
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index d7c9851..757c833 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -743,6 +743,7 @@ static struct ethtool_ops skge_ethtool_o
 	.phys_id	= skge_phys_id,
 	.get_stats_count = skge_get_stats_count,
 	.get_ethtool_stats = skge_get_ethtool_stats,
+	.get_perm_addr	= ethtool_op_get_perm_addr,
 };
 
 /*
@@ -3080,6 +3081,7 @@ static struct net_device *skge_devinit(s
 
 	/* read the mac address */
 	memcpy_fromio(dev->dev_addr, hw->regs + B2_MAC_1 + port*8, ETH_ALEN);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	/* device is off until link detection */
 	netif_carrier_off(dev);
---
0.99.8.GIT


--- NEW FILE 0082-sundance-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] sundance: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536538 -0400

Add support for ETHTOOL_GPERMADDR to sundance.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sundance.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: 93426d6062682766763ecbfe2486727aad06867c
30d60a8288ab6f59939736f5775a7110a8bfff9a
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index d500a57..e148a72 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -549,6 +549,7 @@ static int __devinit sundance_probe1 (st
 	for (i = 0; i < 3; i++)
 		((u16 *)dev->dev_addr)[i] =
 			le16_to_cpu(eeprom_read(ioaddr, i + EEPROM_SA_OFFSET));
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
 	dev->base_addr = (unsigned long)ioaddr;
 	dev->irq = irq;
@@ -1619,6 +1620,7 @@ static struct ethtool_ops ethtool_ops = 
 	.get_link = get_link,
 	.get_msglevel = get_msglevel,
 	.set_msglevel = set_msglevel,
+	.get_perm_addr = ethtool_op_get_perm_addr,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
---
0.99.8.GIT


--- NEW FILE 0083-via-rhine-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] via-rhine: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1126536538 -0400

Add support for ETHTOOL_GPERMADDR to via-rhine.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/via-rhine.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

applies-to: 9d396b32f8f898dd56f5428d4401c9338d6d2a1d
b81e8e1f4a51556586f72711a165bc3a0de230f3
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index fc7738f..e7b4bc3 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -814,8 +814,9 @@ static int __devinit rhine_init_one(stru
 
 	for (i = 0; i < 6; i++)
 		dev->dev_addr[i] = ioread8(ioaddr + StationAddr + i);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 
-	if (!is_valid_ether_addr(dev->dev_addr)) {
+	if (!is_valid_ether_addr(dev->perm_addr)) {
 		rc = -EIO;
 		printk(KERN_ERR "Invalid MAC address\n");
 		goto err_out_unmap;
@@ -1829,6 +1830,7 @@ static struct ethtool_ops netdev_ethtool
 	.set_wol		= rhine_set_wol,
 	.get_sg			= ethtool_op_get_sg,
 	.get_tx_csum		= ethtool_op_get_tx_csum,
+	.get_perm_addr		= ethtool_op_get_perm_addr,
 };
 
 static int netdev_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
---
0.99.8.GIT


--- NEW FILE 0085-drivers-net-fix-up-schedule_timeout-usage.txt ---
Subject: [PATCH] drivers/net: fix-up schedule_timeout() usage
From: Nishanth Aravamudan <nacc at us.ibm.com>
Date: 1126429795 -0700

Use schedule_timeout_interruptible() instead of
set_current_state()/schedule_timeout() to reduce kernel size.

Signed-off-by: Nishanth Aravamudan <nacc at us.ibm.com>
Cc: Jeff Garzik <jgarzik at pobox.com>
Cc: "David S. Miller" <davem at davemloft.net>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/8139cp.c                      |    3 +-
 drivers/net/hp100.c                       |   48 ++++++++++-------------------
 drivers/net/irda/stir4200.c               |    7 ++--
 drivers/net/ixgb/ixgb_ethtool.c           |    7 ++--
 drivers/net/ns83820.c                     |    3 +-
 drivers/net/tokenring/ibmtr.c             |    9 ++---
 drivers/net/tokenring/olympic.c           |    2 +
 drivers/net/tokenring/tms380tr.c          |    3 +-
 drivers/net/typhoon.c                     |    7 ++--
 drivers/net/wan/cosa.c                    |    6 +---
 drivers/net/wan/dscc4.c                   |    9 ++---
 drivers/net/wan/farsync.c                 |    3 +-
 drivers/net/wireless/ipw2100.c            |   17 ++++------
 drivers/net/wireless/prism54/islpci_dev.c |    6 +---
 drivers/net/wireless/prism54/islpci_mgt.c |    5 +--
 include/linux/ibmtr.h                     |    4 +-
 include/linux/netdevice.h                 |    6 +---
 17 files changed, 53 insertions(+), 92 deletions(-)

applies-to: 2713fbd5e71f7a7dbe94634a1bc4eb81a1ed8af5
3173c8907ffb2c64456142da3df2bd0500bd59e0
diff --git a/drivers/net/8139cp.c b/drivers/net/8139cp.c
index ebc20d9..bd99c26 100644
--- a/drivers/net/8139cp.c
+++ b/drivers/net/8139cp.c
@@ -1029,8 +1029,7 @@ static void cp_reset_hw (struct cp_priva
 		if (!(cpr8(Cmd) & CmdReset))
 			return;
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(10);
+		schedule_timeout_uninterruptible(10);
 	}
 
 	printk(KERN_ERR "%s: hardware reset timeout\n", cp->dev->name);
diff --git a/drivers/net/hp100.c b/drivers/net/hp100.c
index cf0ac6f..b71fab6 100644
--- a/drivers/net/hp100.c
+++ b/drivers/net/hp100.c
@@ -2517,10 +2517,8 @@ static int hp100_down_vg_link(struct net
 	do {
 		if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
 			break;
-		if (!in_interrupt()) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		if (!in_interrupt())
+			schedule_timeout_interruptible(1);
 	} while (time_after(time, jiffies));
 
 	if (time_after_eq(jiffies, time))	/* no signal->no logout */
@@ -2536,10 +2534,8 @@ static int hp100_down_vg_link(struct net
 	do {
 		if (!(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
 			break;
-		if (!in_interrupt()) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		if (!in_interrupt())
+			schedule_timeout_interruptible(1);
 	} while (time_after(time, jiffies));
 
 #ifdef HP100_DEBUG
@@ -2577,10 +2573,8 @@ static int hp100_down_vg_link(struct net
 		do {
 			if (!(hp100_inb(MAC_CFG_4) & HP100_MAC_SEL_ST))
 				break;
-			if (!in_interrupt()) {
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(1);
-			}
+			if (!in_interrupt())
+				schedule_timeout_interruptible(1);
 		} while (time_after(time, jiffies));
 
 		hp100_orb(HP100_AUTO_MODE, MAC_CFG_3);	/* Autosel back on */
@@ -2591,10 +2585,8 @@ static int hp100_down_vg_link(struct net
 	do {
 		if ((hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST) == 0)
 			break;
-		if (!in_interrupt()) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		if (!in_interrupt())
+			schedule_timeout_interruptible(1);
 	} while (time_after(time, jiffies));
 
 	if (time_before_eq(time, jiffies)) {
@@ -2606,10 +2598,8 @@ static int hp100_down_vg_link(struct net
 
 	time = jiffies + (2 * HZ);	/* This seems to take a while.... */
 	do {
-		if (!in_interrupt()) {
-			set_current_state(TASK_INTERRUPTIBLE);
-			schedule_timeout(1);
-		}
+		if (!in_interrupt())
+			schedule_timeout_interruptible(1);
 	} while (time_after(time, jiffies));
 
 	return 0;
@@ -2659,10 +2649,8 @@ static int hp100_login_to_vg_hub(struct 
 		do {
 			if (~(hp100_inb(VG_LAN_CFG_1) & HP100_LINK_UP_ST))
 				break;
-			if (!in_interrupt()) {
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(1);
-			}
+			if (!in_interrupt())
+				schedule_timeout_interruptible(1);
 		} while (time_after(time, jiffies));
 
 		/* Start an addressed training and optionally request promiscuous port */
@@ -2697,10 +2685,8 @@ static int hp100_login_to_vg_hub(struct 
 		do {
 			if (hp100_inb(VG_LAN_CFG_1) & HP100_LINK_CABLE_ST)
 				break;
-			if (!in_interrupt()) {
-				set_current_state(TASK_INTERRUPTIBLE);
-				schedule_timeout(1);
-			}
+			if (!in_interrupt())
+				schedule_timeout_interruptible(1);
 		} while (time_before(jiffies, time));
 
 		if (time_after_eq(jiffies, time)) {
@@ -2723,10 +2709,8 @@ static int hp100_login_to_vg_hub(struct 
 #endif
 					break;
 				}
-				if (!in_interrupt()) {
-					set_current_state(TASK_INTERRUPTIBLE);
-					schedule_timeout(1);
-				}
+				if (!in_interrupt())
+					schedule_timeout_interruptible(1);
 			} while (time_after(time, jiffies));
 		}
 
diff --git a/drivers/net/irda/stir4200.c b/drivers/net/irda/stir4200.c
index 15f2073..3961a75 100644
--- a/drivers/net/irda/stir4200.c
+++ b/drivers/net/irda/stir4200.c
@@ -678,10 +678,9 @@ static void turnaround_delay(const struc
 		return;
 
 	ticks = us / (1000000 / HZ);
-	if (ticks > 0) {
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1 + ticks);
-	} else
+	if (ticks > 0)
+		schedule_timeout_interruptible(1 + ticks);
+	else
 		udelay(us);
 }
 
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 319ee4c..04e4718 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -645,11 +645,10 @@ ixgb_phys_id(struct net_device *netdev, 
 
 	mod_timer(&adapter->blink_timer, jiffies);
 
-	set_current_state(TASK_INTERRUPTIBLE);
-	if(data)
-		schedule_timeout(data * HZ);
+	if (data)
+		schedule_timeout_interruptible(data * HZ);
 	else
-		schedule_timeout(MAX_SCHEDULE_TIMEOUT);
+		schedule_timeout_interruptible(MAX_SCHEDULE_TIMEOUT);
 
 	del_timer_sync(&adapter->blink_timer);
 	ixgb_led_off(&adapter->hw);
diff --git a/drivers/net/ns83820.c b/drivers/net/ns83820.c
index e64df4d..ed72a23 100644
--- a/drivers/net/ns83820.c
+++ b/drivers/net/ns83820.c
@@ -1632,8 +1632,7 @@ static void ns83820_run_bist(struct net_
 			timed_out = 1;
 			break;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 	}
 
 	if (status & fail)
diff --git a/drivers/net/tokenring/ibmtr.c b/drivers/net/tokenring/ibmtr.c
index e7b0010..8154bbb 100644
--- a/drivers/net/tokenring/ibmtr.c
+++ b/drivers/net/tokenring/ibmtr.c
@@ -318,7 +318,7 @@ static void ibmtr_cleanup_card(struct ne
 	if (dev->base_addr) {
 		outb(0,dev->base_addr+ADAPTRESET);
 		
-		schedule_timeout(TR_RST_TIME); /* wait 50ms */
+		schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
 
 		outb(0,dev->base_addr+ADAPTRESETREL);
 	}
@@ -859,8 +859,7 @@ static int tok_init_card(struct net_devi
 	writeb(~INT_ENABLE, ti->mmio + ACA_OFFSET + ACA_RESET + ISRP_EVEN);
 	outb(0, PIOaddr + ADAPTRESET);
 
-	current->state=TASK_UNINTERRUPTIBLE;
-	schedule_timeout(TR_RST_TIME); /* wait 50ms */
+	schedule_timeout_uninterruptible(TR_RST_TIME); /* wait 50ms */
 
 	outb(0, PIOaddr + ADAPTRESETREL);
 #ifdef ENABLE_PAGING
@@ -908,8 +907,8 @@ static int tok_open(struct net_device *d
 			DPRINTK("Adapter is up and running\n");
 			return 0;
 		}
-		current->state=TASK_INTERRUPTIBLE;
-		i=schedule_timeout(TR_RETRY_INTERVAL); /* wait 30 seconds */
+		i=schedule_timeout_interruptible(TR_RETRY_INTERVAL);
+							/* wait 30 seconds */
 		if(i!=0) break; /*prob. a signal, like the i>24*HZ case above */
 	}
 	outb(0, dev->base_addr + ADAPTRESET);/* kill pending interrupts*/
diff --git a/drivers/net/tokenring/olympic.c b/drivers/net/tokenring/olympic.c
index 9e79231..05477d2 100644
--- a/drivers/net/tokenring/olympic.c
+++ b/drivers/net/tokenring/olympic.c
@@ -1101,7 +1101,7 @@ static int olympic_close(struct net_devi
 
 	while(olympic_priv->srb_queued) {
 
-		t = schedule_timeout(60*HZ); 
+		t = schedule_timeout_interruptible(60*HZ);
 
         	if(signal_pending(current))	{            
 			printk(KERN_WARNING "%s: SRB timed out.\n",dev->name);
diff --git a/drivers/net/tokenring/tms380tr.c b/drivers/net/tokenring/tms380tr.c
index 2e39bf1..c192559 100644
--- a/drivers/net/tokenring/tms380tr.c
+++ b/drivers/net/tokenring/tms380tr.c
@@ -1243,8 +1243,7 @@ void tms380tr_wait(unsigned long time)
 	
 	tmp = jiffies + time/(1000000/HZ);
 	do {
-  		current->state 		= TASK_INTERRUPTIBLE;
-		tmp = schedule_timeout(tmp);
+		tmp = schedule_timeout_interruptible(tmp);
 	} while(time_after(tmp, jiffies));
 #else
 	udelay(time);
diff --git a/drivers/net/typhoon.c b/drivers/net/typhoon.c
index ecfa6f8..4c76cb7 100644
--- a/drivers/net/typhoon.c
+++ b/drivers/net/typhoon.c
@@ -419,10 +419,9 @@ typhoon_reset(void __iomem *ioaddr, int 
 			   TYPHOON_STATUS_WAITING_FOR_HOST)
 				goto out;
 
-			if(wait_type == WaitSleep) {
-				set_current_state(TASK_UNINTERRUPTIBLE);
-				schedule_timeout(1);
-			} else
+			if(wait_type == WaitSleep)
+				schedule_timeout_uninterruptible(1);
+			else
 				udelay(TYPHOON_UDELAY);
 		}
 
diff --git a/drivers/net/wan/cosa.c b/drivers/net/wan/cosa.c
index 7ff814f..ae9e897 100644
--- a/drivers/net/wan/cosa.c
+++ b/drivers/net/wan/cosa.c
@@ -1617,8 +1617,7 @@ static int get_wait_data(struct cosa_dat
 			return r;
 		}
 		/* sleep if not ready to read */
-		set_current_state(TASK_INTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 	}
 	printk(KERN_INFO "cosa: timeout in get_wait_data (status 0x%x)\n",
 		cosa_getstatus(cosa));
@@ -1644,8 +1643,7 @@ static int put_wait_data(struct cosa_dat
 		}
 #if 0
 		/* sleep if not ready to read */
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
+		schedule_timeout_interruptible(1);
 #endif
 	}
 	printk(KERN_INFO "cosa%d: timeout in put_wait_data (status 0x%x)\n",
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 520a77a..0c1ab4a 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -542,8 +542,7 @@ static int dscc4_wait_ack_cec(struct dsc
 			       msg, i);
 			goto done;
 		}
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(10);
+		schedule_timeout_uninterruptible(10);
 		rmb();
 	} while (++i > 0);
 	printk(KERN_ERR "%s: %s timeout\n", dev->name, msg);
@@ -588,8 +587,7 @@ static inline int dscc4_xpr_ack(struct d
 		    (dpriv->iqtx[cur] & Xpr))
 			break;
 		smp_rmb();
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(10);
+		schedule_timeout_uninterruptible(10);
 	} while (++i > 0);
 
 	return (i >= 0 ) ? i : -EAGAIN;
@@ -1035,8 +1033,7 @@ static void dscc4_pci_reset(struct pci_d
 	/* Flush posted writes */
 	readl(ioaddr + GSTAR);
 
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(10);
+	schedule_timeout_uninterruptible(10);
 
 	for (i = 0; i < 16; i++)
 		pci_write_config_dword(pdev, i << 2, dscc4_pci_config_store[i]);
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 2c83cca..10befb0 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -980,8 +980,7 @@ fst_issue_cmd(struct fst_port_info *port
 	/* Wait for any previous command to complete */
 	while (mbval > NAK) {
 		spin_unlock_irqrestore(&card->card_lock, flags);
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(1);
+		schedule_timeout_uninterruptible(1);
 		spin_lock_irqsave(&card->card_lock, flags);
 
 		if (++safety > 2000) {
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 2414e64..e5cdb5b 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -800,8 +800,7 @@ static int ipw2100_hw_send_command(struc
 	 * doesn't seem to have as many firmware restart cycles...
 	 *
 	 * As a test, we're sticking in a 1/100s delay here */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(HZ / 100);
+	schedule_timeout_uninterruptible(msecs_to_jiffies(10));
 
 	return 0;
 
@@ -1256,8 +1255,7 @@ static int ipw2100_start_adapter(struct 
 	IPW_DEBUG_FW("Waiting for f/w initialization to complete...\n");
 	i = 5000;
 	do {
-  		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(40 * HZ / 1000);
+		schedule_timeout_uninterruptible(msecs_to_jiffies(40));
 		/* Todo... wait for sync command ... */
 
 		read_register(priv->net_dev, IPW_REG_INTA, &inta);
@@ -1411,8 +1409,7 @@ static int ipw2100_hw_phy_off(struct ipw
 		    (val2 & IPW2100_COMMAND_PHY_OFF))
 			return 0;
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		schedule_timeout(HW_PHY_OFF_LOOP_DELAY);
+		schedule_timeout_uninterruptible(HW_PHY_OFF_LOOP_DELAY);
 	}
 
 	return -EIO;
@@ -1466,7 +1463,7 @@ fail_up:
 
 static int ipw2100_hw_stop_adapter(struct ipw2100_priv *priv)
 {
-#define HW_POWER_DOWN_DELAY (HZ / 10)
+#define HW_POWER_DOWN_DELAY (msecs_to_jiffies(100))
 
 	struct host_command cmd = {
 		.host_command = HOST_PRE_POWER_DOWN,
@@ -1520,10 +1517,8 @@ static int ipw2100_hw_stop_adapter(struc
 			printk(KERN_WARNING DRV_NAME ": "
 			       "%s: Power down command failed: Error %d\n",
 			       priv->net_dev->name, err);
-		else {
-			set_current_state(TASK_UNINTERRUPTIBLE);
-			schedule_timeout(HW_POWER_DOWN_DELAY);
-		}
+		else
+			schedule_timeout_uninterruptible(HW_POWER_DOWN_DELAY);
 	}
 
 	priv->status &= ~STATUS_ENABLED;
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 6f13d4a..10cce51 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -439,8 +439,7 @@ prism54_bring_down(islpci_private *priv)
 	wmb();
 
 	/* wait a while for the device to reset */
-	set_current_state(TASK_UNINTERRUPTIBLE);
-	schedule_timeout(50*HZ/1000);
+	schedule_timeout_uninterruptible(msecs_to_jiffies(50));
 
 	return 0;
 }
@@ -491,8 +490,7 @@ islpci_reset_if(islpci_private *priv)
 		/* The software reset acknowledge needs about 220 msec here.
 		 * Be conservative and wait for up to one second. */
 	
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		remaining = schedule_timeout(HZ);
+		remaining = schedule_timeout_uninterruptible(HZ);
 
 		if(remaining > 0) {
 			result = 0;
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index b6f2e5a..4937a5a 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -455,7 +455,7 @@ islpci_mgt_transaction(struct net_device
 		       struct islpci_mgmtframe **recvframe)
 {
 	islpci_private *priv = netdev_priv(ndev);
-	const long wait_cycle_jiffies = (ISL38XX_WAIT_CYCLE * 10 * HZ) / 1000;
+	const long wait_cycle_jiffies = msecs_to_jiffies(ISL38XX_WAIT_CYCLE * 10);
 	long timeout_left = ISL38XX_MAX_WAIT_CYCLES * wait_cycle_jiffies;
 	int err;
 	DEFINE_WAIT(wait);
@@ -475,8 +475,7 @@ islpci_mgt_transaction(struct net_device
 		int timeleft;
 		struct islpci_mgmtframe *frame;
 
-		set_current_state(TASK_UNINTERRUPTIBLE);
-		timeleft = schedule_timeout(wait_cycle_jiffies);
+		timeleft = schedule_timeout_uninterruptible(wait_cycle_jiffies);
 		frame = xchg(&priv->mgmt_received, NULL);
 		if (frame) {
 			if (frame->header->oid == oid) {
diff --git a/include/linux/ibmtr.h b/include/linux/ibmtr.h
index 2ef0b21..1c7a0dd 100644
--- a/include/linux/ibmtr.h
+++ b/include/linux/ibmtr.h
@@ -7,8 +7,8 @@
 /* ported to the Alpha architecture 02/20/96 (just used the HZ macro) */
 
 #define TR_RETRY_INTERVAL	(30*HZ)	/* 500 on PC = 5 s */
-#define TR_RST_TIME		(HZ/20) /* 5 on PC = 50 ms */
-#define TR_BUSY_INTERVAL	(HZ/5)	/* 5 on PC = 200 ms */
+#define TR_RST_TIME		(msecs_to_jiffies(50))	/* 5 on PC = 50 ms */
+#define TR_BUSY_INTERVAL	(msecs_to_jiffies(200))	/* 5 on PC = 200 ms */
 #define TR_SPIN_INTERVAL	(3*HZ)	/* 3 seconds before init timeout */
 
 #define TR_ISA 1
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7c71790..98c98e6 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -852,11 +852,9 @@ static inline void netif_rx_complete(str
 
 static inline void netif_poll_disable(struct net_device *dev)
 {
-	while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state)) {
+	while (test_and_set_bit(__LINK_STATE_RX_SCHED, &dev->state))
 		/* No hurry. */
-		current->state = TASK_INTERRUPTIBLE;
-		schedule_timeout(1);
-	}
+		schedule_timeout_interruptible(1);
 }
 
 static inline void netif_poll_enable(struct net_device *dev)
---
0.99.8.GIT


--- NEW FILE 0086-Replace-drivers-net-wan-custom-ctype-macros-with-standard-ones.txt ---
Subject: [PATCH] Replace drivers/net/wan custom ctype macros with standard ones
From: Tobias Klauser <tklauser at nuerscht.ch>
Date: 1126388700 -0700

Replace the custom is_digit()/is_hex_digit() macros with
isdigit()/isxdigit() from <linux/ctype.h> Additionaly remove unused macro
is_alpha() from <linux/wanpipe.h>

Signed-off-by: Tobias Klauser <tklauser at nuerscht.ch>
Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wan/cycx_x25.c |    5 +++--
 drivers/net/wan/sdla_fr.c  |    4 ++--
 drivers/net/wan/sdla_x25.c |    8 ++++----
 include/linux/cyclomx.h    |    2 --
 include/linux/wanpipe.h    |    9 ---------
 5 files changed, 9 insertions(+), 19 deletions(-)

applies-to: dcd3700a2c37e24a2b5911bb5429aee715684926
8e18d1f9c9dcbf2de5b79cad771ed639983ab6cd
diff --git a/drivers/net/wan/cycx_x25.c b/drivers/net/wan/cycx_x25.c
index 02d57c0..a631d1c 100644
--- a/drivers/net/wan/cycx_x25.c
+++ b/drivers/net/wan/cycx_x25.c
@@ -78,6 +78,7 @@
 
 #define CYCLOMX_X25_DEBUG 1
 
+#include <linux/ctype.h>	/* isdigit() */
 #include <linux/errno.h>	/* return codes */
 #include <linux/if_arp.h>       /* ARPHRD_HWX25 */
 #include <linux/kernel.h>	/* printk(), and other useful stuff */
@@ -418,7 +419,7 @@ static int cycx_wan_new_if(struct wan_de
 
 		/* Set channel timeouts (default if not specified) */
 		chan->idle_tmout = conf->idle_timeout ? conf->idle_timeout : 90;
-	} else if (is_digit(conf->addr[0])) {	/* PVC */
+	} else if (isdigit(conf->addr[0])) {	/* PVC */
 		s16 lcn = dec_to_uint(conf->addr, 0);
 
 		if (lcn >= card->u.x.lo_pvc && lcn <= card->u.x.hi_pvc)
@@ -1531,7 +1532,7 @@ static unsigned dec_to_uint(u8 *str, int
 	if (!len)
 		len = strlen(str);
 
-	for (; len && is_digit(*str); ++str, --len)
+	for (; len && isdigit(*str); ++str, --len)
 		val = (val * 10) + (*str - (unsigned) '0');
 
 	return val;
diff --git a/drivers/net/wan/sdla_fr.c b/drivers/net/wan/sdla_fr.c
index 0497dbd..7f1ce9d 100644
--- a/drivers/net/wan/sdla_fr.c
+++ b/drivers/net/wan/sdla_fr.c
@@ -822,7 +822,7 @@ static int new_if(struct wan_device* wan
 	chan->card = card;
 
 	/* verify media address */
-	if (is_digit(conf->addr[0])) {
+	if (isdigit(conf->addr[0])) {
 
 		dlci = dec_to_uint(conf->addr, 0);
 
@@ -3456,7 +3456,7 @@ static unsigned int dec_to_uint (unsigne
 	if (!len) 
 		len = strlen(str);
 
-	for (val = 0; len && is_digit(*str); ++str, --len)
+	for (val = 0; len && isdigit(*str); ++str, --len)
 		val = (val * 10) + (*str - (unsigned)'0');
 
 	return val;
diff --git a/drivers/net/wan/sdla_x25.c b/drivers/net/wan/sdla_x25.c
index 8a95d61..63f846d 100644
--- a/drivers/net/wan/sdla_x25.c
+++ b/drivers/net/wan/sdla_x25.c
@@ -957,7 +957,7 @@ static int new_if(struct wan_device* wan
 		chan->hold_timeout = (conf->hold_timeout) ? 
 					conf->hold_timeout : 10;
 
-	}else if (is_digit(conf->addr[0])){	/* PVC */
+	}else if (isdigit(conf->addr[0])){	/* PVC */
 		int lcn = dec_to_uint(conf->addr, 0);
 
 		if ((lcn >= card->u.x.lo_pvc) && (lcn <= card->u.x.hi_pvc)){
@@ -3875,7 +3875,7 @@ static unsigned int dec_to_uint (unsigne
 	if (!len) 
 		len = strlen(str);
 
-	for (val = 0; len && is_digit(*str); ++str, --len)
+	for (val = 0; len && isdigit(*str); ++str, --len)
 		val = (val * 10) + (*str - (unsigned)'0');
 	
 	return val;
@@ -3896,9 +3896,9 @@ static unsigned int hex_to_uint (unsigne
 	for (val = 0; len; ++str, --len)
 	{
 		ch = *str;
-		if (is_digit(ch))
+		if (isdigit(ch))
 			val = (val << 4) + (ch - (unsigned)'0');
-		else if (is_hex_digit(ch))
+		else if (isxdigit(ch))
 			val = (val << 4) + ((ch & 0xDF) - (unsigned)'A' + 10);
 		else break;
 	}
diff --git a/include/linux/cyclomx.h b/include/linux/cyclomx.h
index 04fa7df..300d704 100644
--- a/include/linux/cyclomx.h
+++ b/include/linux/cyclomx.h
@@ -37,8 +37,6 @@
 #include <linux/cycx_x25.h>
 #endif
 
-#define	is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
-
 /* Adapter Data Space.
  * This structure is needed because we handle multiple cards, otherwise
  * static data would do it.
diff --git a/include/linux/wanpipe.h b/include/linux/wanpipe.h
index 167d956..dae9860 100644
--- a/include/linux/wanpipe.h
+++ b/include/linux/wanpipe.h
@@ -265,15 +265,6 @@ typedef struct {
 #include <linux/tty_driver.h>
 #include <linux/tty_flip.h>
 
-
-#define	is_digit(ch) (((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')?1:0)
-#define	is_alpha(ch) ((((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'z')||\
-	 	  ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'Z'))?1:0)
-#define	is_hex_digit(ch) ((((ch)>=(unsigned)'0'&&(ch)<=(unsigned)'9')||\
-	 	  ((ch)>=(unsigned)'a'&&(ch)<=(unsigned)'f')||\
-	 	  ((ch)>=(unsigned)'A'&&(ch)<=(unsigned)'F'))?1:0)
-
-
 /****** Data Structures *****************************************************/
 
 /* Adapter Data Space.
---
0.99.8.GIT


--- NEW FILE 0087-drivers-net-wan-possible-cleanups.txt ---
Subject: [PATCH] drivers/net/wan/: possible cleanups
From: Adrian Bunk <bunk at stusta.de>
Date: 1126333048 -0700

This patch contains possible cleanups including the following:
- make needlessly global code static
- #if 0 the following unused global function:
  - sdladrv.c: sdla_intde
- remove the following unused global variable:
  - lmc_media.c: lmc_t1_cables
- remove the following unneeded EXPORT_SYMBOL's:
  - cycx_drv.c: cycx_inten
  - sdladrv.c: sdla_inten
  - sdladrv.c: sdla_intde
  - sdladrv.c: sdla_intack
  - sdladrv.c: sdla_intr
  - syncppp.c: sppp_input
  - syncppp.c: sppp_change_mtu

Signed-off-by: Adrian Bunk <bunk at stusta.de>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wan/cycx_drv.c      |    7 +--
 drivers/net/wan/cycx_main.c     |    2 -
 drivers/net/wan/dscc4.c         |   14 ++++--
 drivers/net/wan/farsync.c       |   24 +++++------
 drivers/net/wan/hdlc_fr.c       |    2 -
 drivers/net/wan/lmc/lmc_debug.c |   10 ++--
 drivers/net/wan/lmc/lmc_media.c |    8 ----
 drivers/net/wan/pc300.h         |   16 -------
 drivers/net/wan/pc300_drv.c     |   87 ++++++++++++++++++++-------------------
 drivers/net/wan/pc300_tty.c     |   18 ++++----
 drivers/net/wan/sdla.c          |   20 ++++-----
 drivers/net/wan/sdladrv.c       |   16 +++----
 drivers/net/wan/syncppp.c       |   10 +---
 include/linux/cycx_drv.h        |    1 
 include/linux/sdladrv.h         |    4 --
 include/net/syncppp.h           |    1 
 16 files changed, 101 insertions(+), 139 deletions(-)

applies-to: c17ceb7190fa7dfd5ad743a9af8b7a4b43aa2d7b
7665a08928f241247afe8c76865cdbe4ef5489bf
diff --git a/drivers/net/wan/cycx_drv.c b/drivers/net/wan/cycx_drv.c
index 9e56fc3..e6d0057 100644
--- a/drivers/net/wan/cycx_drv.c
+++ b/drivers/net/wan/cycx_drv.c
@@ -109,7 +109,7 @@ static long cycx_2x_irq_options[]  = { 7
  *		< 0	error.
  * Context:	process */
 
-int __init cycx_drv_init(void)
+static int __init cycx_drv_init(void)
 {
 	printk(KERN_INFO "%s v%u.%u %s\n", fullname, MOD_VERSION, MOD_RELEASE,
 			 copyright);
@@ -119,7 +119,7 @@ int __init cycx_drv_init(void)
 
 /* Module 'remove' entry point.
  * o release all remaining system resources */
-void cycx_drv_cleanup(void)
+static void cycx_drv_cleanup(void)
 {
 }
 
@@ -184,8 +184,7 @@ int cycx_down(struct cycx_hw *hw)
 }
 
 /* Enable interrupt generation.  */
-EXPORT_SYMBOL(cycx_inten);
-void cycx_inten(struct cycx_hw *hw)
+static void cycx_inten(struct cycx_hw *hw)
 {
 	writeb(0, hw->dpmbase);
 }
diff --git a/drivers/net/wan/cycx_main.c b/drivers/net/wan/cycx_main.c
index 7b48064..430b1f6 100644
--- a/drivers/net/wan/cycx_main.c
+++ b/drivers/net/wan/cycx_main.c
@@ -103,7 +103,7 @@ static struct cycx_device *cycx_card_arr
  *		< 0	error.
  * Context:	process
  */
-int __init cycx_init(void)
+static int __init cycx_init(void)
 {
 	int cnt, err = -ENOMEM;
 
diff --git a/drivers/net/wan/dscc4.c b/drivers/net/wan/dscc4.c
index 0c1ab4a..2f61a47 100644
--- a/drivers/net/wan/dscc4.c
+++ b/drivers/net/wan/dscc4.c
@@ -446,8 +446,8 @@ static inline unsigned int dscc4_tx_quie
 	return readl(dpriv->base_addr + CH0FTDA + dpriv->dev_id*4) == dpriv->ltda;
 }
 
-int state_check(u32 state, struct dscc4_dev_priv *dpriv, struct net_device *dev,
-		const char *msg)
+static int state_check(u32 state, struct dscc4_dev_priv *dpriv,
+		       struct net_device *dev, const char *msg)
 {
 	int ret = 0;
 
@@ -466,8 +466,9 @@ int state_check(u32 state, struct dscc4_
 	return ret;
 }
 
-void dscc4_tx_print(struct net_device *dev, struct dscc4_dev_priv *dpriv,
-		    char *msg)
+static void dscc4_tx_print(struct net_device *dev,
+			   struct dscc4_dev_priv *dpriv,
+			   char *msg)
 {
 	printk(KERN_DEBUG "%s: tx_current=%02d tx_dirty=%02d (%s)\n",
 	       dev->name, dpriv->tx_current, dpriv->tx_dirty, msg);
@@ -507,7 +508,8 @@ static void dscc4_release_ring(struct ds
 	}
 }
 
-inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv, struct net_device *dev)
+static inline int try_get_rx_skb(struct dscc4_dev_priv *dpriv,
+				 struct net_device *dev)
 {
 	unsigned int dirty = dpriv->rx_dirty%RX_RING_SIZE;
 	struct RxFD *rx_fd = dpriv->rx_fd + dirty;
@@ -1891,7 +1893,7 @@ try:
  * It failed and locked solid. Thus the introduction of a dummy skb.
  * Problem is acknowledged in errata sheet DS5. Joy :o/
  */
-struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
+static struct sk_buff *dscc4_init_dummy_skb(struct dscc4_dev_priv *dpriv)
 {
 	struct sk_buff *skb;
 
diff --git a/drivers/net/wan/farsync.c b/drivers/net/wan/farsync.c
index 10befb0..7981a2c 100644
--- a/drivers/net/wan/farsync.c
+++ b/drivers/net/wan/farsync.c
@@ -74,11 +74,11 @@ MODULE_LICENSE("GPL");
 /*
  * Modules parameters and associated varaibles
  */
-int fst_txq_low = FST_LOW_WATER_MARK;
-int fst_txq_high = FST_HIGH_WATER_MARK;
-int fst_max_reads = 7;
-int fst_excluded_cards = 0;
-int fst_excluded_list[FST_MAX_CARDS];
+static int fst_txq_low = FST_LOW_WATER_MARK;
+static int fst_txq_high = FST_HIGH_WATER_MARK;
+static int fst_max_reads = 7;
+static int fst_excluded_cards = 0;
+static int fst_excluded_list[FST_MAX_CARDS];
 
 module_param(fst_txq_low, int, 0);
 module_param(fst_txq_high, int, 0);
@@ -572,13 +572,13 @@ static void do_bottom_half_rx(struct fst
 static void fst_process_tx_work_q(unsigned long work_q);
 static void fst_process_int_work_q(unsigned long work_q);
 
-DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
-DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
+static DECLARE_TASKLET(fst_tx_task, fst_process_tx_work_q, 0);
+static DECLARE_TASKLET(fst_int_task, fst_process_int_work_q, 0);
 
-struct fst_card_info *fst_card_array[FST_MAX_CARDS];
-spinlock_t fst_work_q_lock;
-u64 fst_work_txq;
-u64 fst_work_intq;
+static struct fst_card_info *fst_card_array[FST_MAX_CARDS];
+static spinlock_t fst_work_q_lock;
+static u64 fst_work_txq;
+static u64 fst_work_intq;
 
 static void
 fst_q_work_item(u64 * queue, int card_index)
@@ -1497,7 +1497,7 @@ do_bottom_half_rx(struct fst_card_info *
  *      The interrupt service routine
  *      Dev_id is our fst_card_info pointer
  */
-irqreturn_t
+static irqreturn_t
 fst_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct fst_card_info *card;
diff --git a/drivers/net/wan/hdlc_fr.c b/drivers/net/wan/hdlc_fr.c
index a5d6891..e1601d3 100644
--- a/drivers/net/wan/hdlc_fr.c
+++ b/drivers/net/wan/hdlc_fr.c
@@ -330,7 +330,7 @@ static int pvc_close(struct net_device *
 
 
 
-int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int pvc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	pvc_device *pvc = dev_to_pvc(dev);
 	fr_proto_pvc_info info;
diff --git a/drivers/net/wan/lmc/lmc_debug.c b/drivers/net/wan/lmc/lmc_debug.c
index 9dccd95..3b94352 100644
--- a/drivers/net/wan/lmc/lmc_debug.c
+++ b/drivers/net/wan/lmc/lmc_debug.c
@@ -8,10 +8,10 @@
 /*
  * Prints out len, max to 80 octets using printk, 20 per line
  */
-void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
-{
 #ifdef DEBUG
 #ifdef LMC_PACKET_LOG
+void lmcConsoleLog(char *type, unsigned char *ucData, int iLen)
+{
   int iNewLine = 1;
   char str[80], *pstr;
   
@@ -43,26 +43,24 @@ void lmcConsoleLog(char *type, unsigned 
     }
   sprintf(pstr, "\n");
   printk(str);
+}
 #endif
 #endif
-}
 
 #ifdef DEBUG
 u_int32_t lmcEventLogIndex = 0;
 u_int32_t lmcEventLogBuf[LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS];
-#endif
 
 void lmcEventLog (u_int32_t EventNum, u_int32_t arg2, u_int32_t arg3)
 {
-#ifdef DEBUG
   lmcEventLogBuf[lmcEventLogIndex++] = EventNum;
   lmcEventLogBuf[lmcEventLogIndex++] = arg2;
   lmcEventLogBuf[lmcEventLogIndex++] = arg3;
   lmcEventLogBuf[lmcEventLogIndex++] = jiffies;
 
   lmcEventLogIndex &= (LMC_EVENTLOGSIZE * LMC_EVENTLOGARGS) - 1;
-#endif
 }
+#endif  /*  DEBUG  */
 
 void lmc_trace(struct net_device *dev, char *msg){
 #ifdef LMC_TRACE
diff --git a/drivers/net/wan/lmc/lmc_media.c b/drivers/net/wan/lmc/lmc_media.c
index f55ce76..af8b55f 100644
--- a/drivers/net/wan/lmc/lmc_media.c
+++ b/drivers/net/wan/lmc/lmc_media.c
@@ -48,14 +48,6 @@
   */
 
 /*
- * For lack of a better place, put the SSI cable stuff here.
- */
-char *lmc_t1_cables[] = {
-  "V.10/RS423", "EIA530A", "reserved", "X.21", "V.35",
-  "EIA449/EIA530/V.36", "V.28/EIA232", "none", NULL
-};
-
-/*
  * protocol independent method.
  */
 static void lmc_set_protocol (lmc_softc_t * const, lmc_ctl_t *);
diff --git a/drivers/net/wan/pc300.h b/drivers/net/wan/pc300.h
index 73401b0..2024b26 100644
--- a/drivers/net/wan/pc300.h
+++ b/drivers/net/wan/pc300.h
@@ -472,24 +472,8 @@ enum pc300_loopback_cmds {
 
 #ifdef __KERNEL__
 /* Function Prototypes */
-int dma_buf_write(pc300_t *, int, ucchar *, int);
-int dma_buf_read(pc300_t *, int, struct sk_buff *);
 void tx_dma_start(pc300_t *, int);
-void rx_dma_start(pc300_t *, int);
-void tx_dma_stop(pc300_t *, int);
-void rx_dma_stop(pc300_t *, int);
-int cpc_queue_xmit(struct sk_buff *, struct net_device *);
-void cpc_net_rx(struct net_device *);
-void cpc_sca_status(pc300_t *, int);
-int cpc_change_mtu(struct net_device *, int);
-int cpc_ioctl(struct net_device *, struct ifreq *, int);
-int ch_config(pc300dev_t *);
-int rx_config(pc300dev_t *);
-int tx_config(pc300dev_t *);
-void cpc_opench(pc300dev_t *);
-void cpc_closech(pc300dev_t *);
 int cpc_open(struct net_device *dev);
-int cpc_close(struct net_device *dev);
 int cpc_set_media(hdlc_device *, int);
 #endif /* __KERNEL__ */
 
diff --git a/drivers/net/wan/pc300_drv.c b/drivers/net/wan/pc300_drv.c
index 3e7753b..a3e65d1 100644
--- a/drivers/net/wan/pc300_drv.c
+++ b/drivers/net/wan/pc300_drv.c
@@ -291,6 +291,7 @@ static uclong detect_ram(pc300_t *);
 static void plx_init(pc300_t *);
 static void cpc_trace(struct net_device *, struct sk_buff *, char);
 static int cpc_attach(struct net_device *, unsigned short, unsigned short);
+static int cpc_close(struct net_device *dev);
 
 #ifdef CONFIG_PC300_MLPPP
 void cpc_tty_init(pc300dev_t * dev);
@@ -437,7 +438,7 @@ static void rx_dma_buf_check(pc300_t * c
 	printk("\n");
 }
 
-int dma_get_rx_frame_size(pc300_t * card, int ch)
+static int dma_get_rx_frame_size(pc300_t * card, int ch)
 {
 	volatile pcsca_bd_t __iomem *ptdescr;
 	ucshort first_bd = card->chan[ch].rx_first_bd;
@@ -462,7 +463,7 @@ int dma_get_rx_frame_size(pc300_t * card
  * dma_buf_write: writes a frame to the Tx DMA buffers
  * NOTE: this function writes one frame at a time.
  */
-int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
+static int dma_buf_write(pc300_t * card, int ch, ucchar * ptdata, int len)
 {
 	int i, nchar;
 	volatile pcsca_bd_t __iomem *ptdescr;
@@ -503,7 +504,7 @@ int dma_buf_write(pc300_t * card, int ch
  * dma_buf_read: reads a frame from the Rx DMA buffers
  * NOTE: this function reads one frame at a time.
  */
-int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
+static int dma_buf_read(pc300_t * card, int ch, struct sk_buff *skb)
 {
 	int nchar;
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -560,7 +561,7 @@ int dma_buf_read(pc300_t * card, int ch,
 	return (rcvd);
 }
 
-void tx_dma_stop(pc300_t * card, int ch)
+static void tx_dma_stop(pc300_t * card, int ch)
 {
 	void __iomem *scabase = card->hw.scabase;
 	ucchar drr_ena_bit = 1 << (5 + 2 * ch);
@@ -571,7 +572,7 @@ void tx_dma_stop(pc300_t * card, int ch)
 	cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
 }
 
-void rx_dma_stop(pc300_t * card, int ch)
+static void rx_dma_stop(pc300_t * card, int ch)
 {
 	void __iomem *scabase = card->hw.scabase;
 	ucchar drr_ena_bit = 1 << (4 + 2 * ch);
@@ -582,7 +583,7 @@ void rx_dma_stop(pc300_t * card, int ch)
 	cpc_writeb(scabase + DRR, drr_rst_bit & ~drr_ena_bit);
 }
 
-void rx_dma_start(pc300_t * card, int ch)
+static void rx_dma_start(pc300_t * card, int ch)
 {
 	void __iomem *scabase = card->hw.scabase;
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -607,7 +608,7 @@ void rx_dma_start(pc300_t * card, int ch
 /*************************/
 /***   FALC Routines   ***/
 /*************************/
-void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
+static void falc_issue_cmd(pc300_t * card, int ch, ucchar cmd)
 {
 	void __iomem *falcbase = card->hw.falcbase;
 	unsigned long i = 0;
@@ -622,7 +623,7 @@ void falc_issue_cmd(pc300_t * card, int 
 	cpc_writeb(falcbase + F_REG(CMDR, ch), cmd);
 }
 
-void falc_intr_enable(pc300_t * card, int ch)
+static void falc_intr_enable(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -672,7 +673,7 @@ void falc_intr_enable(pc300_t * card, in
 	}
 }
 
-void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
+static void falc_open_timeslot(pc300_t * card, int ch, int timeslot)
 {
 	void __iomem *falcbase = card->hw.falcbase;
 	ucchar tshf = card->chan[ch].falc.offset;
@@ -688,7 +689,7 @@ void falc_open_timeslot(pc300_t * card, 
 			(0x80 >> (timeslot & 0x07)));
 }
 
-void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
+static void falc_close_timeslot(pc300_t * card, int ch, int timeslot)
 {
 	void __iomem *falcbase = card->hw.falcbase;
 	ucchar tshf = card->chan[ch].falc.offset;
@@ -704,7 +705,7 @@ void falc_close_timeslot(pc300_t * card,
 		   ~(0x80 >> (timeslot & 0x07)));
 }
 
-void falc_close_all_timeslots(pc300_t * card, int ch)
+static void falc_close_all_timeslots(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -726,7 +727,7 @@ void falc_close_all_timeslots(pc300_t * 
 	}
 }
 
-void falc_open_all_timeslots(pc300_t * card, int ch)
+static void falc_open_all_timeslots(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -758,7 +759,7 @@ void falc_open_all_timeslots(pc300_t * c
 	}
 }
 
-void falc_init_timeslot(pc300_t * card, int ch)
+static void falc_init_timeslot(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -776,7 +777,7 @@ void falc_init_timeslot(pc300_t * card, 
 	}
 }
 
-void falc_enable_comm(pc300_t * card, int ch)
+static void falc_enable_comm(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
@@ -792,7 +793,7 @@ void falc_enable_comm(pc300_t * card, in
 		   ~((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
 }
 
-void falc_disable_comm(pc300_t * card, int ch)
+static void falc_disable_comm(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
@@ -806,7 +807,7 @@ void falc_disable_comm(pc300_t * card, i
 		   ((CPLD_REG1_FALC_DCD | CPLD_REG1_FALC_CTS) << (2 * ch)));
 }
 
-void falc_init_t1(pc300_t * card, int ch)
+static void falc_init_t1(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -975,7 +976,7 @@ void falc_init_t1(pc300_t * card, int ch
 	falc_close_all_timeslots(card, ch);
 }
 
-void falc_init_e1(pc300_t * card, int ch)
+static void falc_init_e1(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1155,7 +1156,7 @@ void falc_init_e1(pc300_t * card, int ch
 	falc_close_all_timeslots(card, ch);
 }
 
-void falc_init_hdlc(pc300_t * card, int ch)
+static void falc_init_hdlc(pc300_t * card, int ch)
 {
 	void __iomem *falcbase = card->hw.falcbase;
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
@@ -1181,7 +1182,7 @@ void falc_init_hdlc(pc300_t * card, int 
 	falc_intr_enable(card, ch);
 }
 
-void te_config(pc300_t * card, int ch)
+static void te_config(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1241,7 +1242,7 @@ void te_config(pc300_t * card, int ch)
 	CPC_UNLOCK(card, flags);
 }
 
-void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
+static void falc_check_status(pc300_t * card, int ch, unsigned char frs0)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1397,7 +1398,7 @@ void falc_check_status(pc300_t * card, i
 	}
 }
 
-void falc_update_stats(pc300_t * card, int ch)
+static void falc_update_stats(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1450,7 +1451,7 @@ void falc_update_stats(pc300_t * card, i
  *		the synchronizer and then sent to the system interface.
  *----------------------------------------------------------------------------
  */
-void falc_remote_loop(pc300_t * card, int ch, int loop_on)
+static void falc_remote_loop(pc300_t * card, int ch, int loop_on)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1495,7 +1496,7 @@ void falc_remote_loop(pc300_t * card, in
  *		coding must be identical.
  *----------------------------------------------------------------------------
  */
-void falc_local_loop(pc300_t * card, int ch, int loop_on)
+static void falc_local_loop(pc300_t * card, int ch, int loop_on)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1522,7 +1523,7 @@ void falc_local_loop(pc300_t * card, int
  *		looped. They are originated by the FALC-LH transmitter.
  *----------------------------------------------------------------------------
  */
-void falc_payload_loop(pc300_t * card, int ch, int loop_on)
+static void falc_payload_loop(pc300_t * card, int ch, int loop_on)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1576,7 +1577,7 @@ void falc_payload_loop(pc300_t * card, i
  * Description:	Turns XLU bit off in the proper register
  *----------------------------------------------------------------------------
  */
-void turn_off_xlu(pc300_t * card, int ch)
+static void turn_off_xlu(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1597,7 +1598,7 @@ void turn_off_xlu(pc300_t * card, int ch
  * Description: Turns XLD bit off in the proper register
  *----------------------------------------------------------------------------
  */
-void turn_off_xld(pc300_t * card, int ch)
+static void turn_off_xld(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1619,7 +1620,7 @@ void turn_off_xld(pc300_t * card, int ch
  *		to generate a LOOP activation code over a T1/E1 line.
  *----------------------------------------------------------------------------
  */
-void falc_generate_loop_up_code(pc300_t * card, int ch)
+static void falc_generate_loop_up_code(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1652,7 +1653,7 @@ void falc_generate_loop_up_code(pc300_t 
  *		to generate a LOOP deactivation code over a T1/E1 line.
  *----------------------------------------------------------------------------
  */
-void falc_generate_loop_down_code(pc300_t * card, int ch)
+static void falc_generate_loop_down_code(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1682,7 +1683,7 @@ void falc_generate_loop_down_code(pc300_
  *		it on the reception side.
  *----------------------------------------------------------------------------
  */
-void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
+static void falc_pattern_test(pc300_t * card, int ch, unsigned int activate)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -1729,7 +1730,7 @@ void falc_pattern_test(pc300_t * card, i
  * Description:	This routine returns the bit error counter value
  *----------------------------------------------------------------------------
  */
-ucshort falc_pattern_test_error(pc300_t * card, int ch)
+static ucshort falc_pattern_test_error(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = (pc300ch_t *) & card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
@@ -1769,7 +1770,7 @@ cpc_trace(struct net_device *dev, struct
 	netif_rx(skb);
 }
 
-void cpc_tx_timeout(struct net_device *dev)
+static void cpc_tx_timeout(struct net_device *dev)
 {
 	pc300dev_t *d = (pc300dev_t *) dev->priv;
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -1797,7 +1798,7 @@ void cpc_tx_timeout(struct net_device *d
 	netif_wake_queue(dev);
 }
 
-int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
+static int cpc_queue_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	pc300dev_t *d = (pc300dev_t *) dev->priv;
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -1880,7 +1881,7 @@ int cpc_queue_xmit(struct sk_buff *skb, 
 	return 0;
 }
 
-void cpc_net_rx(struct net_device *dev)
+static void cpc_net_rx(struct net_device *dev)
 {
 	pc300dev_t *d = (pc300dev_t *) dev->priv;
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
@@ -2403,7 +2404,7 @@ static irqreturn_t cpc_intr(int irq, voi
 	return IRQ_HANDLED;
 }
 
-void cpc_sca_status(pc300_t * card, int ch)
+static void cpc_sca_status(pc300_t * card, int ch)
 {
 	ucchar ilar;
 	void __iomem *scabase = card->hw.scabase;
@@ -2495,7 +2496,7 @@ void cpc_sca_status(pc300_t * card, int 
 	}
 }
 
-void cpc_falc_status(pc300_t * card, int ch)
+static void cpc_falc_status(pc300_t * card, int ch)
 {
 	pc300ch_t *chan = &card->chan[ch];
 	falc_t *pfalc = (falc_t *) & chan->falc;
@@ -2523,7 +2524,7 @@ void cpc_falc_status(pc300_t * card, int
 	CPC_UNLOCK(card, flags);
 }
 
-int cpc_change_mtu(struct net_device *dev, int new_mtu)
+static int cpc_change_mtu(struct net_device *dev, int new_mtu)
 {
 	if ((new_mtu < 128) || (new_mtu > PC300_DEF_MTU))
 		return -EINVAL;
@@ -2531,7 +2532,7 @@ int cpc_change_mtu(struct net_device *de
 	return 0;
 }
 
-int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static int cpc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	pc300dev_t *d = (pc300dev_t *) dev->priv;
@@ -2856,7 +2857,7 @@ static int clock_rate_calc(uclong rate, 
 	}
 }
 
-int ch_config(pc300dev_t * d)
+static int ch_config(pc300dev_t * d)
 {
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
 	pc300chconf_t *conf = (pc300chconf_t *) & chan->conf;
@@ -3004,7 +3005,7 @@ int ch_config(pc300dev_t * d)
 	return 0;
 }
 
-int rx_config(pc300dev_t * d)
+static int rx_config(pc300dev_t * d)
 {
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
 	pc300_t *card = (pc300_t *) chan->card;
@@ -3035,7 +3036,7 @@ int rx_config(pc300dev_t * d)
 	return 0;
 }
 
-int tx_config(pc300dev_t * d)
+static int tx_config(pc300dev_t * d)
 {
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
 	pc300_t *card = (pc300_t *) chan->card;
@@ -3098,7 +3099,7 @@ static int cpc_attach(struct net_device 
 	return 0;
 }
 
-void cpc_opench(pc300dev_t * d)
+static void cpc_opench(pc300dev_t * d)
 {
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
 	pc300_t *card = (pc300_t *) chan->card;
@@ -3116,7 +3117,7 @@ void cpc_opench(pc300dev_t * d)
 		   cpc_readb(scabase + M_REG(CTL, ch)) & ~(CTL_RTS | CTL_DTR));
 }
 
-void cpc_closech(pc300dev_t * d)
+static void cpc_closech(pc300dev_t * d)
 {
 	pc300ch_t *chan = (pc300ch_t *) d->chan;
 	pc300_t *card = (pc300_t *) chan->card;
@@ -3173,7 +3174,7 @@ int cpc_open(struct net_device *dev)
 	return 0;
 }
 
-int cpc_close(struct net_device *dev)
+static int cpc_close(struct net_device *dev)
 {
 	hdlc_device *hdlc = dev_to_hdlc(dev);
 	pc300dev_t *d = (pc300dev_t *) dev->priv;
diff --git a/drivers/net/wan/pc300_tty.c b/drivers/net/wan/pc300_tty.c
index 8454bf6..52f26b9 100644
--- a/drivers/net/wan/pc300_tty.c
+++ b/drivers/net/wan/pc300_tty.c
@@ -112,10 +112,10 @@ typedef	struct _st_cpc_tty_area {
 static struct tty_driver serial_drv;
 
 /* local variables */
-st_cpc_tty_area	cpc_tty_area[CPC_TTY_NPORTS];
+static st_cpc_tty_area	cpc_tty_area[CPC_TTY_NPORTS];
 
-int cpc_tty_cnt=0;	/* number of intrfaces configured with MLPPP */
-int cpc_tty_unreg_flag = 0;
+static int cpc_tty_cnt = 0;	/* number of intrfaces configured with MLPPP */
+static int cpc_tty_unreg_flag = 0;
 
 /* TTY functions prototype */
 static int cpc_tty_open(struct tty_struct *tty, struct file *flip);
@@ -132,9 +132,9 @@ static void cpc_tty_trace(pc300dev_t *de
 static void cpc_tty_signal_off(pc300dev_t *pc300dev, unsigned char);
 static void cpc_tty_signal_on(pc300dev_t *pc300dev, unsigned char);
 
-int pc300_tiocmset(struct tty_struct *, struct file *,
-			unsigned int, unsigned int);
-int pc300_tiocmget(struct tty_struct *, struct file *);
+static int pc300_tiocmset(struct tty_struct *, struct file *,
+			  unsigned int, unsigned int);
+static int pc300_tiocmget(struct tty_struct *, struct file *);
 
 /* functions called by PC300 driver */
 void cpc_tty_init(pc300dev_t *dev);
@@ -538,8 +538,8 @@ static int cpc_tty_chars_in_buffer(struc
 	return(0); 
 } 
 
-int pc300_tiocmset(struct tty_struct *tty, struct file *file,
-			unsigned int set, unsigned int clear)
+static int pc300_tiocmset(struct tty_struct *tty, struct file *file,
+			  unsigned int set, unsigned int clear)
 {
 	st_cpc_tty_area    *cpc_tty; 
 
@@ -565,7 +565,7 @@ int pc300_tiocmset(struct tty_struct *tt
 	return 0;
 }
 
-int pc300_tiocmget(struct tty_struct *tty, struct file *file)
+static int pc300_tiocmget(struct tty_struct *tty, struct file *file)
 {
 	unsigned int result;
 	unsigned char status;
diff --git a/drivers/net/wan/sdla.c b/drivers/net/wan/sdla.c
index 3ac9a45..036adc4 100644
--- a/drivers/net/wan/sdla.c
+++ b/drivers/net/wan/sdla.c
@@ -182,7 +182,7 @@ static char sdla_byte(struct net_device 
 	return(byte);
 }
 
-void sdla_stop(struct net_device *dev)
+static void sdla_stop(struct net_device *dev)
 {
 	struct frad_local *flp;
 
@@ -209,7 +209,7 @@ void sdla_stop(struct net_device *dev)
 	}
 }
 
-void sdla_start(struct net_device *dev)
+static void sdla_start(struct net_device *dev)
 {
 	struct frad_local *flp;
 
@@ -247,7 +247,7 @@ void sdla_start(struct net_device *dev)
  *
  ***************************************************/
 
-int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
+static int sdla_z80_poll(struct net_device *dev, int z80_addr, int jiffs, char resp1, char resp2)
 {
 	unsigned long start, done, now;
 	char          resp, *temp;
@@ -505,7 +505,7 @@ static int sdla_cmd(struct net_device *d
 
 static int sdla_reconfig(struct net_device *dev);
 
-int sdla_activate(struct net_device *slave, struct net_device *master)
+static int sdla_activate(struct net_device *slave, struct net_device *master)
 {
 	struct frad_local *flp;
 	int i;
@@ -527,7 +527,7 @@ int sdla_activate(struct net_device *sla
 	return(0);
 }
 
-int sdla_deactivate(struct net_device *slave, struct net_device *master)
+static int sdla_deactivate(struct net_device *slave, struct net_device *master)
 {
 	struct frad_local *flp;
 	int               i;
@@ -549,7 +549,7 @@ int sdla_deactivate(struct net_device *s
 	return(0);
 }
 
-int sdla_assoc(struct net_device *slave, struct net_device *master)
+static int sdla_assoc(struct net_device *slave, struct net_device *master)
 {
 	struct frad_local *flp;
 	int               i;
@@ -585,7 +585,7 @@ int sdla_assoc(struct net_device *slave,
 	return(0);
 }
 
-int sdla_deassoc(struct net_device *slave, struct net_device *master)
+static int sdla_deassoc(struct net_device *slave, struct net_device *master)
 {
 	struct frad_local *flp;
 	int               i;
@@ -613,7 +613,7 @@ int sdla_deassoc(struct net_device *slav
 	return(0);
 }
 
-int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
+static int sdla_dlci_conf(struct net_device *slave, struct net_device *master, int get)
 {
 	struct frad_local *flp;
 	struct dlci_local *dlp;
@@ -1324,7 +1324,7 @@ NOTE:  This is rather a useless action r
 	return(0);
 }
 
-int sdla_change_mtu(struct net_device *dev, int new_mtu)
+static int sdla_change_mtu(struct net_device *dev, int new_mtu)
 {
 	struct frad_local *flp;
 
@@ -1337,7 +1337,7 @@ int sdla_change_mtu(struct net_device *d
 	return(-EOPNOTSUPP);
 }
 
-int sdla_set_config(struct net_device *dev, struct ifmap *map)
+static int sdla_set_config(struct net_device *dev, struct ifmap *map)
 {
 	struct frad_local *flp;
 	int               i;
diff --git a/drivers/net/wan/sdladrv.c b/drivers/net/wan/sdladrv.c
index c8bc6da..7c2cf2e 100644
--- a/drivers/net/wan/sdladrv.c
+++ b/drivers/net/wan/sdladrv.c
@@ -642,9 +642,7 @@ int sdla_mapmem (sdlahw_t* hw, unsigned 
  * Enable interrupt generation.
  */
 
-EXPORT_SYMBOL(sdla_inten);
-
-int sdla_inten (sdlahw_t* hw)
+static int sdla_inten (sdlahw_t* hw)
 {
 	unsigned port = hw->port;
 	int tmp, i;
@@ -698,8 +696,7 @@ int sdla_inten (sdlahw_t* hw)
  * Disable interrupt generation.
  */
 
-EXPORT_SYMBOL(sdla_intde);
-
+#if 0
 int sdla_intde (sdlahw_t* hw)
 {
 	unsigned port = hw->port;
@@ -748,14 +745,13 @@ int sdla_intde (sdlahw_t* hw)
 	}
 	return 0;
 }
+#endif  /*  0  */
 
 /*============================================================================
  * Acknowledge SDLA hardware interrupt.
  */
 
-EXPORT_SYMBOL(sdla_intack);
-
-int sdla_intack (sdlahw_t* hw)
+static int sdla_intack (sdlahw_t* hw)
 {
 	unsigned port = hw->port;
 	int tmp;
@@ -827,8 +823,7 @@ void read_S514_int_stat (sdlahw_t* hw, u
  * Generate an interrupt to adapter's CPU.
  */
 
-EXPORT_SYMBOL(sdla_intr);
-
+#if 0
 int sdla_intr (sdlahw_t* hw)
 {
 	unsigned port = hw->port;
@@ -863,6 +858,7 @@ int sdla_intr (sdlahw_t* hw)
 	}
 	return 0;
 }
+#endif  /*  0  */
 
 /*============================================================================
  * Execute Adapter Command.
diff --git a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
index b56a7b5..3731b22 100644
--- a/drivers/net/wan/syncppp.c
+++ b/drivers/net/wan/syncppp.c
@@ -221,7 +221,7 @@ static void sppp_clear_timeout(struct sp
  *	here.
  */
  
-void sppp_input (struct net_device *dev, struct sk_buff *skb)
+static void sppp_input (struct net_device *dev, struct sk_buff *skb)
 {
 	struct ppp_header *h;
 	struct sppp *sp = (struct sppp *)sppp_of(dev);
@@ -355,8 +355,6 @@ done:
 	return;
 }
 
-EXPORT_SYMBOL(sppp_input);
-
 /*
  *	Handle transmit packets.
  */
@@ -990,7 +988,7 @@ EXPORT_SYMBOL(sppp_reopen);
  *	the mtu is out of range.
  */
  
-int sppp_change_mtu(struct net_device *dev, int new_mtu)
+static int sppp_change_mtu(struct net_device *dev, int new_mtu)
 {
 	if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP))
 		return -EINVAL;
@@ -998,8 +996,6 @@ int sppp_change_mtu(struct net_device *d
 	return 0;
 }
 
-EXPORT_SYMBOL(sppp_change_mtu);
-
 /**
  *	sppp_do_ioctl - Ioctl handler for ppp/hdlc
  *	@dev: Device subject to ioctl
@@ -1456,7 +1452,7 @@ static int sppp_rcv(struct sk_buff *skb,
 	return 0;
 }
 
-struct packet_type sppp_packet_type = {
+static struct packet_type sppp_packet_type = {
 	.type	= __constant_htons(ETH_P_WAN_PPP),
 	.func	= sppp_rcv,
 };
diff --git a/include/linux/cycx_drv.h b/include/linux/cycx_drv.h
index 6621df8..12fe6b0 100644
--- a/include/linux/cycx_drv.h
+++ b/include/linux/cycx_drv.h
@@ -60,6 +60,5 @@ extern int cycx_peek(struct cycx_hw *hw,
 extern int cycx_poke(struct cycx_hw *hw, u32 addr, void *buf, u32 len);
 extern int cycx_exec(void __iomem *addr);
 
-extern void cycx_inten(struct cycx_hw *hw);
 extern void cycx_intr(struct cycx_hw *hw);
 #endif	/* _CYCX_DRV_H */
diff --git a/include/linux/sdladrv.h b/include/linux/sdladrv.h
index 78f6340..c85e103 100644
--- a/include/linux/sdladrv.h
+++ b/include/linux/sdladrv.h
@@ -52,12 +52,8 @@ typedef struct sdlahw
 
 extern int sdla_setup	(sdlahw_t* hw, void* sfm, unsigned len);
 extern int sdla_down	(sdlahw_t* hw);
-extern int sdla_inten	(sdlahw_t* hw);
-extern int sdla_intde	(sdlahw_t* hw);
-extern int sdla_intack	(sdlahw_t* hw);
 extern void S514_intack  (sdlahw_t* hw, u32 int_status);
 extern void read_S514_int_stat (sdlahw_t* hw, u32* int_status);
-extern int sdla_intr	(sdlahw_t* hw);
 extern int sdla_mapmem	(sdlahw_t* hw, unsigned long addr);
 extern int sdla_peek	(sdlahw_t* hw, unsigned long addr, void* buf,
 			 unsigned len);
diff --git a/include/net/syncppp.h b/include/net/syncppp.h
index 614cb6b..877efa4 100644
--- a/include/net/syncppp.h
+++ b/include/net/syncppp.h
@@ -86,7 +86,6 @@ static inline struct sppp *sppp_of(struc
 
 void sppp_attach (struct ppp_device *pd);
 void sppp_detach (struct net_device *dev);
-void sppp_input (struct net_device *dev, struct sk_buff *m);
 int sppp_do_ioctl (struct net_device *dev, struct ifreq *ifr, int cmd);
 struct sk_buff *sppp_dequeue (struct net_device *dev);
 int sppp_isempty (struct net_device *dev);
---
0.99.8.GIT


--- NEW FILE 0088-lne390-bogus-casts.txt ---
Subject: [PATCH] lne390 bogus casts
From: viro at ZenIV.linux.org.uk <viro at ZenIV.linux.org.uk>
Date: 1126282934 +0100

	We already have the iomem pointer we need...
Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/lne390.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 99b4dceff3f8210e7c0420053b2433977d7f0322
387d890db88b4eb7c1dd55a2a0c16d6f0dccc7ad
diff --git a/drivers/net/lne390.c b/drivers/net/lne390.c
index 27f0d8a..309d254 100644
--- a/drivers/net/lne390.c
+++ b/drivers/net/lne390.c
@@ -298,7 +298,7 @@ static int __init lne390_probe1(struct n
 	return 0;
 unmap:
 	if (ei_status.reg0)
-		iounmap((void *)dev->mem_start);
+		iounmap(ei_status.mem);
 cleanup:
 	free_irq(dev->irq, dev);
 	return ret;
---
0.99.8.GIT


--- NEW FILE 0089-C99-initializers-in-ray_cs.c.txt ---
Subject: [PATCH] C99 initializers in ray_cs.c
From: viro at ZenIV.linux.org.uk <viro at ZenIV.linux.org.uk>
Date: 1126294823 +0100

Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/ray_cs.c |   46 +++++++++++++++++++++--------------------
 1 files changed, 23 insertions(+), 23 deletions(-)

applies-to: aa18b1e9c91b43cccc76949bba8b2c56b5b8cfed
7a700fafbed55eee2cc766fbe47cf68e229da281
diff --git a/drivers/net/wireless/ray_cs.c b/drivers/net/wireless/ray_cs.c
index e9c5ea0..70fd6fd 100644
--- a/drivers/net/wireless/ray_cs.c
+++ b/drivers/net/wireless/ray_cs.c
@@ -1649,28 +1649,28 @@ static iw_stats * ray_get_wireless_stats
  */
 
 static const iw_handler	ray_handler[] = {
-	[SIOCSIWCOMMIT-SIOCIWFIRST] (iw_handler) ray_commit,
-	[SIOCGIWNAME  -SIOCIWFIRST] (iw_handler) ray_get_name,
-	[SIOCSIWFREQ  -SIOCIWFIRST] (iw_handler) ray_set_freq,
-	[SIOCGIWFREQ  -SIOCIWFIRST] (iw_handler) ray_get_freq,
-	[SIOCSIWMODE  -SIOCIWFIRST] (iw_handler) ray_set_mode,
-	[SIOCGIWMODE  -SIOCIWFIRST] (iw_handler) ray_get_mode,
-	[SIOCGIWRANGE -SIOCIWFIRST] (iw_handler) ray_get_range,
+	[SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) ray_commit,
+	[SIOCGIWNAME  -SIOCIWFIRST] = (iw_handler) ray_get_name,
+	[SIOCSIWFREQ  -SIOCIWFIRST] = (iw_handler) ray_set_freq,
+	[SIOCGIWFREQ  -SIOCIWFIRST] = (iw_handler) ray_get_freq,
+	[SIOCSIWMODE  -SIOCIWFIRST] = (iw_handler) ray_set_mode,
+	[SIOCGIWMODE  -SIOCIWFIRST] = (iw_handler) ray_get_mode,
+	[SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) ray_get_range,
 #ifdef WIRELESS_SPY
- 	[SIOCSIWSPY   -SIOCIWFIRST] (iw_handler) iw_handler_set_spy,
-	[SIOCGIWSPY   -SIOCIWFIRST] (iw_handler) iw_handler_get_spy,
-	[SIOCSIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_set_thrspy,
-	[SIOCGIWTHRSPY-SIOCIWFIRST] (iw_handler) iw_handler_get_thrspy,
+ 	[SIOCSIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_set_spy,
+	[SIOCGIWSPY   -SIOCIWFIRST] = (iw_handler) iw_handler_get_spy,
+	[SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_set_thrspy,
+	[SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) iw_handler_get_thrspy,
 #endif	/* WIRELESS_SPY */
-	[SIOCGIWAP    -SIOCIWFIRST] (iw_handler) ray_get_wap,
-	[SIOCSIWESSID -SIOCIWFIRST] (iw_handler) ray_set_essid,
-	[SIOCGIWESSID -SIOCIWFIRST] (iw_handler) ray_get_essid,
-	[SIOCSIWRATE  -SIOCIWFIRST] (iw_handler) ray_set_rate,
-	[SIOCGIWRATE  -SIOCIWFIRST] (iw_handler) ray_get_rate,
-	[SIOCSIWRTS   -SIOCIWFIRST] (iw_handler) ray_set_rts,
-	[SIOCGIWRTS   -SIOCIWFIRST] (iw_handler) ray_get_rts,
-	[SIOCSIWFRAG  -SIOCIWFIRST] (iw_handler) ray_set_frag,
-	[SIOCGIWFRAG  -SIOCIWFIRST] (iw_handler) ray_get_frag,
+	[SIOCGIWAP    -SIOCIWFIRST] = (iw_handler) ray_get_wap,
+	[SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) ray_set_essid,
+	[SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) ray_get_essid,
+	[SIOCSIWRATE  -SIOCIWFIRST] = (iw_handler) ray_set_rate,
+	[SIOCGIWRATE  -SIOCIWFIRST] = (iw_handler) ray_get_rate,
+	[SIOCSIWRTS   -SIOCIWFIRST] = (iw_handler) ray_set_rts,
+	[SIOCGIWRTS   -SIOCIWFIRST] = (iw_handler) ray_get_rts,
+	[SIOCSIWFRAG  -SIOCIWFIRST] = (iw_handler) ray_set_frag,
+	[SIOCGIWFRAG  -SIOCIWFIRST] = (iw_handler) ray_get_frag,
 };
 
 #define SIOCSIPFRAMING	SIOCIWFIRSTPRIV		/* Set framing mode */
@@ -1678,9 +1678,9 @@ static const iw_handler	ray_handler[] = 
 #define SIOCGIPCOUNTRY	SIOCIWFIRSTPRIV + 3	/* Get country code */
 
 static const iw_handler	ray_private_handler[] = {
-	[0] (iw_handler) ray_set_framing,
-	[1] (iw_handler) ray_get_framing,
-	[3] (iw_handler) ray_get_country,
+	[0] = (iw_handler) ray_set_framing,
+	[1] = (iw_handler) ray_get_framing,
+	[3] = (iw_handler) ray_get_country,
 };
 
 static const struct iw_priv_args	ray_private_args[] = {
---
0.99.8.GIT


--- NEW FILE 0090-mii-Add-test-for-GigE-support.txt ---
Subject: [PATCH] mii: Add test for GigE support
From: Dale Farnsworth <dale at farnsworth.org>
Date: 1124818229 -0700

Signed-off-by: Dale Farnsworth <dale at farnsworth.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/mii.c   |   15 +++++++++++++++
 include/linux/mii.h |    1 +
 2 files changed, 16 insertions(+), 0 deletions(-)

applies-to: b52a9c14808a61c1ff5c320d380fea08793968d9
43ec6e95e4d8a73afc2405a44b955c380aeeb65a
diff --git a/drivers/net/mii.c b/drivers/net/mii.c
index c33cb3d..e42aa79 100644
--- a/drivers/net/mii.c
+++ b/drivers/net/mii.c
@@ -207,6 +207,20 @@ int mii_ethtool_sset(struct mii_if_info 
 	return 0;
 }
 
+int mii_check_gmii_support(struct mii_if_info *mii)
+{
+	int reg;
+
+	reg = mii->mdio_read(mii->dev, mii->phy_id, MII_BMSR);
+	if (reg & BMSR_ESTATEN) {
+		reg = mii->mdio_read(mii->dev, mii->phy_id, MII_ESTATUS);
+		if (reg & (ESTATUS_1000_TFULL | ESTATUS_1000_THALF))
+			return 1;
+	}
+
+	return 0;
+}
+
 int mii_link_ok (struct mii_if_info *mii)
 {
 	/* first, a dummy read, needed to latch some MII phys */
@@ -394,5 +408,6 @@ EXPORT_SYMBOL(mii_ethtool_gset);
 EXPORT_SYMBOL(mii_ethtool_sset);
 EXPORT_SYMBOL(mii_check_link);
 EXPORT_SYMBOL(mii_check_media);
+EXPORT_SYMBOL(mii_check_gmii_support);
 EXPORT_SYMBOL(generic_mii_ioctl);
 
diff --git a/include/linux/mii.h b/include/linux/mii.h
index 9b8d047..68f5a0f 100644
--- a/include/linux/mii.h
+++ b/include/linux/mii.h
@@ -158,6 +158,7 @@ extern int mii_link_ok (struct mii_if_in
 extern int mii_nway_restart (struct mii_if_info *mii);
 extern int mii_ethtool_gset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
 extern int mii_ethtool_sset(struct mii_if_info *mii, struct ethtool_cmd *ecmd);
+extern int mii_check_gmii_support(struct mii_if_info *mii);
 extern void mii_check_link (struct mii_if_info *mii);
 extern unsigned int mii_check_media (struct mii_if_info *mii,
 				     unsigned int ok_to_print,
---
0.99.8.GIT


--- NEW FILE 0099-pcnet32-set_ringparam-implementation.txt ---
Subject: [PATCH] pcnet32: set_ringparam implementation
From: Hubert WS Lin <wslin at tw.ibm.com>
Date: 1126723165 -0700

This patch implements the set_ringparam(), one of the ethtool operations,
which allows changing tx/rx ring sizes via ethtool.

- Changed memery allocation of tx/rx ring from static to dynamic
- Implemented set_ringparam()
- Tested on i386 and ppc64

Signed-off-by: Hubert WS Lin <wslin at tw.ibm.com>
Signed-off-by: Jay Vosburgh <fubar at us.ibm.com>
Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/pcnet32.c |  263 +++++++++++++++++++++++++++++++++++++++----------
 1 files changed, 209 insertions(+), 54 deletions(-)

applies-to: f33440ed3f4ba3594d6c3316bdcdda420ce11801
eabf04151682bc7b57c84fea58cf9e4e5a3cf2a9
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 6c3731b..7350c27 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -22,8 +22,8 @@
  *************************************************************************/
 
 #define DRV_NAME	"pcnet32"
-#define DRV_VERSION	"1.30j"
-#define DRV_RELDATE	"29.04.2005"
+#define DRV_VERSION	"1.31"
+#define DRV_RELDATE	"02.Sep.2005"
 #define PFX		DRV_NAME ": "
 
 static const char *version =
@@ -257,6 +257,7 @@ static int homepna[MAX_UNITS];
  * v1.30h  24 Jun 2004 Don Fry correctly select auto, speed, duplex in bcr32.
  * v1.30i  28 Jun 2004 Don Fry change to use module_param.
  * v1.30j  29 Apr 2005 Don Fry fix skb/map leak with loopback test.
+ * v1.31   02 Sep 2005 Hubert WS Lin <wslin at tw.ibm.c0m> added set_ringparam().
  */
 
 
@@ -266,17 +267,17 @@ static int homepna[MAX_UNITS];
  * That translates to 2 (4 == 2^^2) and 4 (16 == 2^^4).
  */
 #ifndef PCNET32_LOG_TX_BUFFERS
-#define PCNET32_LOG_TX_BUFFERS 4
-#define PCNET32_LOG_RX_BUFFERS 5
+#define PCNET32_LOG_TX_BUFFERS		4
+#define PCNET32_LOG_RX_BUFFERS		5
+#define PCNET32_LOG_MAX_TX_BUFFERS	9	/* 2^9 == 512 */
+#define PCNET32_LOG_MAX_RX_BUFFERS	9
 #endif
 
 #define TX_RING_SIZE		(1 << (PCNET32_LOG_TX_BUFFERS))
-#define TX_RING_MOD_MASK	(TX_RING_SIZE - 1)
-#define TX_RING_LEN_BITS	((PCNET32_LOG_TX_BUFFERS) << 12)
+#define TX_MAX_RING_SIZE	(1 << (PCNET32_LOG_MAX_TX_BUFFERS))
 
 #define RX_RING_SIZE		(1 << (PCNET32_LOG_RX_BUFFERS))
-#define RX_RING_MOD_MASK	(RX_RING_SIZE - 1)
-#define RX_RING_LEN_BITS	((PCNET32_LOG_RX_BUFFERS) << 4)
+#define RX_MAX_RING_SIZE	(1 << (PCNET32_LOG_MAX_RX_BUFFERS))
 
 #define PKT_BUF_SZ		1544
 
@@ -339,8 +340,8 @@ struct pcnet32_access {
  */
 struct pcnet32_private {
     /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
-    struct pcnet32_rx_head    rx_ring[RX_RING_SIZE];
-    struct pcnet32_tx_head    tx_ring[TX_RING_SIZE];
+    struct pcnet32_rx_head    *rx_ring;
+    struct pcnet32_tx_head    *tx_ring;
     struct pcnet32_init_block init_block;
     dma_addr_t		dma_addr;	/* DMA address of beginning of this
 					   object, returned by
@@ -349,13 +350,21 @@ struct pcnet32_private {
 					   structure */
     const char		*name;
     /* The saved address of a sent-in-place packet/buffer, for skfree(). */
-    struct sk_buff	*tx_skbuff[TX_RING_SIZE];
-    struct sk_buff	*rx_skbuff[RX_RING_SIZE];
-    dma_addr_t		tx_dma_addr[TX_RING_SIZE];
-    dma_addr_t		rx_dma_addr[RX_RING_SIZE];
+    struct sk_buff	**tx_skbuff;
+    struct sk_buff	**rx_skbuff;
+    dma_addr_t		*tx_dma_addr;
+    dma_addr_t		*rx_dma_addr;
     struct pcnet32_access	a;
     spinlock_t		lock;		/* Guard lock */
     unsigned int	cur_rx, cur_tx;	/* The next free ring entry */
+    unsigned int	rx_ring_size;	/* current rx ring size */
+    unsigned int	tx_ring_size;	/* current tx ring size */
+    unsigned int	rx_mod_mask;	/* rx ring modular mask */
+    unsigned int	tx_mod_mask;	/* tx ring modular mask */
+    unsigned short	rx_len_bits;
+    unsigned short	tx_len_bits;
+    dma_addr_t		rx_ring_dma_addr;
+    dma_addr_t		tx_ring_dma_addr;
     unsigned int	dirty_rx, dirty_tx; /* The ring entries to be free()ed. */
     struct net_device_stats stats;
     char		tx_full;
@@ -397,6 +406,9 @@ static int pcnet32_get_regs_len(struct n
 static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
 	void *ptr);
 static void pcnet32_purge_tx_ring(struct net_device *dev);
+static int pcnet32_alloc_ring(struct net_device *dev);
+static void pcnet32_free_ring(struct net_device *dev);
+
 
 enum pci_flags_bit {
     PCI_USES_IO=1, PCI_USES_MEM=2, PCI_USES_MASTER=4,
@@ -613,10 +625,59 @@ static void pcnet32_get_ringparam(struct
 {
     struct pcnet32_private *lp = dev->priv;
 
-    ering->tx_max_pending = TX_RING_SIZE - 1;
-    ering->tx_pending = lp->cur_tx - lp->dirty_tx;
-    ering->rx_max_pending = RX_RING_SIZE - 1;
-    ering->rx_pending = lp->cur_rx & RX_RING_MOD_MASK;
+    ering->tx_max_pending = TX_MAX_RING_SIZE - 1;
+    ering->tx_pending = lp->tx_ring_size - 1;
+    ering->rx_max_pending = RX_MAX_RING_SIZE - 1;
+    ering->rx_pending = lp->rx_ring_size - 1;
+}
+
+static int pcnet32_set_ringparam(struct net_device *dev, struct ethtool_ringparam *ering)
+{
+    struct pcnet32_private *lp = dev->priv;
+    unsigned long flags;
+    int i;
+
+    if (ering->rx_mini_pending || ering->rx_jumbo_pending)
+	return -EINVAL;
+
+    if (netif_running(dev))
+	pcnet32_close(dev);
+
+    spin_lock_irqsave(&lp->lock, flags);
+    pcnet32_free_ring(dev);
+    lp->tx_ring_size = min(ering->tx_pending, (unsigned int) TX_MAX_RING_SIZE);
+    lp->rx_ring_size = min(ering->rx_pending, (unsigned int) RX_MAX_RING_SIZE);
+
+    for (i = 0; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
+	if (lp->tx_ring_size <= (1 << i))
+	    break;
+    }
+    lp->tx_ring_size = (1 << i);
+    lp->tx_mod_mask = lp->tx_ring_size - 1;
+    lp->tx_len_bits = (i << 12);
+
+    for (i = 0; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
+	if (lp->rx_ring_size <= (1 << i))
+	    break;
+    }
+    lp->rx_ring_size = (1 << i);
+    lp->rx_mod_mask = lp->rx_ring_size - 1;
+    lp->rx_len_bits = (i << 4);
+
+    if (pcnet32_alloc_ring(dev)) {
+	pcnet32_free_ring(dev);
+	return -ENOMEM;
+    }
+
+    spin_unlock_irqrestore(&lp->lock, flags);
+
+    if (pcnet32_debug & NETIF_MSG_DRV)
+	printk(KERN_INFO PFX "Ring Param Settings: RX: %d, TX: %d\n", lp->rx_ring_size, lp->tx_ring_size);
+
+    if (netif_running(dev))
+	pcnet32_open(dev);
+
+    return 0;
 }
 
 static void pcnet32_get_strings(struct net_device *dev, u32 stringset, u8 *data)
@@ -948,6 +1009,7 @@ static struct ethtool_ops pcnet32_ethtoo
     .nway_reset		= pcnet32_nway_reset,
     .get_link		= pcnet32_get_link,
     .get_ringparam	= pcnet32_get_ringparam,
+    .set_ringparam	= pcnet32_set_ringparam,
     .get_tx_csum	= ethtool_op_get_tx_csum,
     .get_sg		= ethtool_op_get_sg,
     .get_tso		= ethtool_op_get_tso,
@@ -1241,6 +1303,12 @@ pcnet32_probe1(unsigned long ioaddr, int
     dev->priv = lp;
     lp->name = chipname;
     lp->shared_irq = shared;
+    lp->tx_ring_size = TX_RING_SIZE;		/* default tx ring size */
+    lp->rx_ring_size = RX_RING_SIZE;		/* default rx ring size */
+    lp->tx_mod_mask = lp->tx_ring_size - 1;
+    lp->rx_mod_mask = lp->rx_ring_size - 1;
+    lp->tx_len_bits = (PCNET32_LOG_TX_BUFFERS << 12);
+    lp->rx_len_bits = (PCNET32_LOG_RX_BUFFERS << 4);
     lp->mii_if.full_duplex = fdx;
     lp->mii_if.phy_id_mask = 0x1f;
     lp->mii_if.reg_num_mask = 0x1f;
@@ -1267,21 +1335,23 @@ pcnet32_probe1(unsigned long ioaddr, int
     }
     lp->a = *a;
 
+    if (pcnet32_alloc_ring(dev)) {
+	ret = -ENOMEM;
+	goto err_free_ring;
+    }
     /* detect special T1/E1 WAN card by checking for MAC address */
     if (dev->dev_addr[0] == 0x00 && dev->dev_addr[1] == 0xe0
 	    && dev->dev_addr[2] == 0x75)
 	lp->options = PCNET32_PORT_FD | PCNET32_PORT_GPSI;
 
     lp->init_block.mode = le16_to_cpu(0x0003);	/* Disable Rx and Tx. */
-    lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
+    lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
     for (i = 0; i < 6; i++)
 	lp->init_block.phys_addr[i] = dev->dev_addr[i];
     lp->init_block.filter[0] = 0x00000000;
     lp->init_block.filter[1] = 0x00000000;
-    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
-	    offsetof(struct pcnet32_private, rx_ring));
-    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
-	    offsetof(struct pcnet32_private, tx_ring));
+    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
+    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
 
     /* switch pcnet32 to 32bit mode */
     a->write_bcr(ioaddr, 20, 2);
@@ -1312,7 +1382,7 @@ pcnet32_probe1(unsigned long ioaddr, int
 	    if (pcnet32_debug & NETIF_MSG_PROBE)
 		printk(", failed to detect IRQ line.\n");
 	    ret = -ENODEV;
-	    goto err_free_consistent;
+	    goto err_free_ring;
 	}
 	if (pcnet32_debug & NETIF_MSG_PROBE)
 	    printk(", probed IRQ %d.\n", dev->irq);
@@ -1343,7 +1413,7 @@ pcnet32_probe1(unsigned long ioaddr, int
 
     /* Fill in the generic fields of the device structure. */
     if (register_netdev(dev))
-	goto err_free_consistent;
+	goto err_free_ring;
 
     if (pdev) {
 	pci_set_drvdata(pdev, dev);
@@ -1361,6 +1431,8 @@ pcnet32_probe1(unsigned long ioaddr, int
 
     return 0;
 
+err_free_ring:
+    pcnet32_free_ring(dev);
 err_free_consistent:
     pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
 err_free_netdev:
@@ -1371,6 +1443,86 @@ err_release_region:
 }
 
 
+static int pcnet32_alloc_ring(struct net_device *dev)
+{
+    struct pcnet32_private *lp = dev->priv;
+
+    if ((lp->tx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+	&lp->tx_ring_dma_addr)) == NULL) {
+	if (pcnet32_debug & NETIF_MSG_DRV)
+	    printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
+	return -ENOMEM;
+    }
+
+    if ((lp->rx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+	&lp->rx_ring_dma_addr)) == NULL) {
+	if (pcnet32_debug & NETIF_MSG_DRV)
+	    printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
+	return -ENOMEM;
+    }
+
+    if (!(lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size, GFP_ATOMIC))) {
+	if (pcnet32_debug & NETIF_MSG_DRV)
+	    printk(KERN_ERR PFX "Memory allocation failed.\n");
+	return -ENOMEM;
+    }
+    memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size);
+
+    if (!(lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size, GFP_ATOMIC))) {
+	if (pcnet32_debug & NETIF_MSG_DRV)
+	    printk(KERN_ERR PFX "Memory allocation failed.\n");
+	return -ENOMEM;
+    }
+    memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size);
+
+    if (!(lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size, GFP_ATOMIC))) {
+	if (pcnet32_debug & NETIF_MSG_DRV)
+	    printk(KERN_ERR PFX "Memory allocation failed.\n");
+	return -ENOMEM;
+    }
+    memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size);
+
+    if (!(lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size, GFP_ATOMIC))) {
+	if (pcnet32_debug & NETIF_MSG_DRV)
+	    printk(KERN_ERR PFX "Memory allocation failed.\n");
+	return -ENOMEM;
+    }
+    memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size);
+
+    return 0;
+}
+
+
+static void pcnet32_free_ring(struct net_device *dev)
+{
+    struct pcnet32_private *lp = dev->priv;
+
+    kfree(lp->tx_skbuff);
+    lp->tx_skbuff = NULL;
+
+    kfree(lp->rx_skbuff);
+    lp->rx_skbuff = NULL;
+
+    kfree(lp->tx_dma_addr);
+    lp->tx_dma_addr = NULL;
+
+    kfree(lp->rx_dma_addr);
+    lp->rx_dma_addr = NULL;
+
+    if (lp->tx_ring) {
+	pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+		lp->tx_ring, lp->tx_ring_dma_addr);
+	lp->tx_ring = NULL;
+    }
+
+    if (lp->rx_ring) {
+	pci_free_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+		lp->rx_ring, lp->rx_ring_dma_addr);
+	lp->rx_ring = NULL;
+    }
+}
+
+
 static int
 pcnet32_open(struct net_device *dev)
 {
@@ -1402,8 +1554,8 @@ pcnet32_open(struct net_device *dev)
     if (netif_msg_ifup(lp))
 	printk(KERN_DEBUG "%s: pcnet32_open() irq %d tx/rx rings %#x/%#x init %#x.\n",
 	       dev->name, dev->irq,
-	       (u32) (lp->dma_addr + offsetof(struct pcnet32_private, tx_ring)),
-	       (u32) (lp->dma_addr + offsetof(struct pcnet32_private, rx_ring)),
+	       (u32) (lp->tx_ring_dma_addr),
+	       (u32) (lp->rx_ring_dma_addr),
 	       (u32) (lp->dma_addr + offsetof(struct pcnet32_private, init_block)));
 
     /* set/reset autoselect bit */
@@ -1523,7 +1675,7 @@ pcnet32_open(struct net_device *dev)
 
 err_free_ring:
     /* free any allocated skbuffs */
-    for (i = 0; i < RX_RING_SIZE; i++) {
+    for (i = 0; i < lp->rx_ring_size; i++) {
 	lp->rx_ring[i].status = 0;
 	if (lp->rx_skbuff[i]) {
 	    pci_unmap_single(lp->pci_dev, lp->rx_dma_addr[i], PKT_BUF_SZ-2,
@@ -1533,6 +1685,9 @@ err_free_ring:
 	lp->rx_skbuff[i] = NULL;
 	lp->rx_dma_addr[i] = 0;
     }
+
+    pcnet32_free_ring(dev);
+
     /*
      * Switch back to 16bit mode to avoid problems with dumb
      * DOS packet driver after a warm reboot
@@ -1564,7 +1719,7 @@ pcnet32_purge_tx_ring(struct net_device 
     struct pcnet32_private *lp = dev->priv;
     int i;
 
-    for (i = 0; i < TX_RING_SIZE; i++) {
+    for (i = 0; i < lp->tx_ring_size; i++) {
 	lp->tx_ring[i].status = 0;	/* CPU owns buffer */
 	wmb();	/* Make sure adapter sees owner change */
 	if (lp->tx_skbuff[i]) {
@@ -1589,7 +1744,7 @@ pcnet32_init_ring(struct net_device *dev
     lp->cur_rx = lp->cur_tx = 0;
     lp->dirty_rx = lp->dirty_tx = 0;
 
-    for (i = 0; i < RX_RING_SIZE; i++) {
+    for (i = 0; i < lp->rx_ring_size; i++) {
 	struct sk_buff *rx_skbuff = lp->rx_skbuff[i];
 	if (rx_skbuff == NULL) {
 	    if (!(rx_skbuff = lp->rx_skbuff[i] = dev_alloc_skb (PKT_BUF_SZ))) {
@@ -1613,20 +1768,18 @@ pcnet32_init_ring(struct net_device *dev
     }
     /* The Tx buffer address is filled in as needed, but we do need to clear
      * the upper ownership bit. */
-    for (i = 0; i < TX_RING_SIZE; i++) {
+    for (i = 0; i < lp->tx_ring_size; i++) {
 	lp->tx_ring[i].status = 0;	/* CPU owns buffer */
 	wmb();	/* Make sure adapter sees owner change */
 	lp->tx_ring[i].base = 0;
 	lp->tx_dma_addr[i] = 0;
     }
 
-    lp->init_block.tlen_rlen = le16_to_cpu(TX_RING_LEN_BITS | RX_RING_LEN_BITS);
+    lp->init_block.tlen_rlen = le16_to_cpu(lp->tx_len_bits | lp->rx_len_bits);
     for (i = 0; i < 6; i++)
 	lp->init_block.phys_addr[i] = dev->dev_addr[i];
-    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->dma_addr +
-	    offsetof(struct pcnet32_private, rx_ring));
-    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->dma_addr +
-	    offsetof(struct pcnet32_private, tx_ring));
+    lp->init_block.rx_ring = (u32)le32_to_cpu(lp->rx_ring_dma_addr);
+    lp->init_block.tx_ring = (u32)le32_to_cpu(lp->tx_ring_dma_addr);
     wmb();	/* Make sure all changes are visible */
     return 0;
 }
@@ -1684,13 +1837,13 @@ pcnet32_tx_timeout (struct net_device *d
 	printk(KERN_DEBUG " Ring data dump: dirty_tx %d cur_tx %d%s cur_rx %d.",
 	   lp->dirty_tx, lp->cur_tx, lp->tx_full ? " (full)" : "",
 	   lp->cur_rx);
-	for (i = 0 ; i < RX_RING_SIZE; i++)
+	for (i = 0 ; i < lp->rx_ring_size; i++)
 	printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
 	       le32_to_cpu(lp->rx_ring[i].base),
 	       (-le16_to_cpu(lp->rx_ring[i].buf_length)) & 0xffff,
 	       le32_to_cpu(lp->rx_ring[i].msg_length),
 	       le16_to_cpu(lp->rx_ring[i].status));
-	for (i = 0 ; i < TX_RING_SIZE; i++)
+	for (i = 0 ; i < lp->tx_ring_size; i++)
 	printk("%s %08x %04x %08x %04x", i & 1 ? "" : "\n ",
 	       le32_to_cpu(lp->tx_ring[i].base),
 	       (-le16_to_cpu(lp->tx_ring[i].length)) & 0xffff,
@@ -1731,7 +1884,7 @@ pcnet32_start_xmit(struct sk_buff *skb, 
     /* Fill in a Tx ring entry */
 
     /* Mask to ring buffer boundary. */
-    entry = lp->cur_tx & TX_RING_MOD_MASK;
+    entry = lp->cur_tx & lp->tx_mod_mask;
 
     /* Caution: the write order is important here, set the status
      * with the "ownership" bits last. */
@@ -1755,7 +1908,7 @@ pcnet32_start_xmit(struct sk_buff *skb, 
 
     dev->trans_start = jiffies;
 
-    if (lp->tx_ring[(entry+1) & TX_RING_MOD_MASK].base != 0) {
+    if (lp->tx_ring[(entry+1) & lp->tx_mod_mask].base != 0) {
 	lp->tx_full = 1;
 	netif_stop_queue(dev);
     }
@@ -1808,7 +1961,7 @@ pcnet32_interrupt(int irq, void *dev_id,
 	    int delta;
 
 	    while (dirty_tx != lp->cur_tx) {
-		int entry = dirty_tx & TX_RING_MOD_MASK;
+		int entry = dirty_tx & lp->tx_mod_mask;
 		int status = (short)le16_to_cpu(lp->tx_ring[entry].status);
 
 		if (status < 0)
@@ -1866,18 +2019,18 @@ pcnet32_interrupt(int irq, void *dev_id,
 		dirty_tx++;
 	    }
 
-	    delta = (lp->cur_tx - dirty_tx) & (TX_RING_MOD_MASK + TX_RING_SIZE);
-	    if (delta > TX_RING_SIZE) {
+	    delta = (lp->cur_tx - dirty_tx) & (lp->tx_mod_mask + lp->tx_ring_size);
+	    if (delta > lp->tx_ring_size) {
 		if (netif_msg_drv(lp))
 		    printk(KERN_ERR "%s: out-of-sync dirty pointer, %d vs. %d, full=%d.\n",
 			    dev->name, dirty_tx, lp->cur_tx, lp->tx_full);
-		dirty_tx += TX_RING_SIZE;
-		delta -= TX_RING_SIZE;
+		dirty_tx += lp->tx_ring_size;
+		delta -= lp->tx_ring_size;
 	    }
 
 	    if (lp->tx_full &&
 		netif_queue_stopped(dev) &&
-		delta < TX_RING_SIZE - 2) {
+		delta < lp->tx_ring_size - 2) {
 		/* The ring is no longer full, clear tbusy. */
 		lp->tx_full = 0;
 		netif_wake_queue (dev);
@@ -1934,8 +2087,8 @@ static int
 pcnet32_rx(struct net_device *dev)
 {
     struct pcnet32_private *lp = dev->priv;
-    int entry = lp->cur_rx & RX_RING_MOD_MASK;
-    int boguscnt = RX_RING_SIZE / 2;
+    int entry = lp->cur_rx & lp->rx_mod_mask;
+    int boguscnt = lp->rx_ring_size / 2;
 
     /* If we own the next entry, it's a new packet. Send it up. */
     while ((short)le16_to_cpu(lp->rx_ring[entry].status) >= 0) {
@@ -2000,12 +2153,12 @@ pcnet32_rx(struct net_device *dev)
 		    if (netif_msg_drv(lp))
 			printk(KERN_ERR "%s: Memory squeeze, deferring packet.\n",
 				dev->name);
-		    for (i = 0; i < RX_RING_SIZE; i++)
+		    for (i = 0; i < lp->rx_ring_size; i++)
 			if ((short)le16_to_cpu(lp->rx_ring[(entry+i)
-				    & RX_RING_MOD_MASK].status) < 0)
+				    & lp->rx_mod_mask].status) < 0)
 			    break;
 
-		    if (i > RX_RING_SIZE -2) {
+		    if (i > lp->rx_ring_size -2) {
 			lp->stats.rx_dropped++;
 			lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
 			wmb();	/* Make sure adapter sees owner change */
@@ -2043,7 +2196,7 @@ pcnet32_rx(struct net_device *dev)
 	lp->rx_ring[entry].buf_length = le16_to_cpu(2-PKT_BUF_SZ);
 	wmb(); /* Make sure owner changes after all others are visible */
 	lp->rx_ring[entry].status |= le16_to_cpu(0x8000);
-	entry = (++lp->cur_rx) & RX_RING_MOD_MASK;
+	entry = (++lp->cur_rx) & lp->rx_mod_mask;
 	if (--boguscnt <= 0) break;	/* don't stay in loop forever */
     }
 
@@ -2086,7 +2239,7 @@ pcnet32_close(struct net_device *dev)
     spin_lock_irqsave(&lp->lock, flags);
 
     /* free all allocated skbuffs */
-    for (i = 0; i < RX_RING_SIZE; i++) {
+    for (i = 0; i < lp->rx_ring_size; i++) {
 	lp->rx_ring[i].status = 0;
 	wmb();		/* Make sure adapter sees owner change */
 	if (lp->rx_skbuff[i]) {
@@ -2098,7 +2251,7 @@ pcnet32_close(struct net_device *dev)
 	lp->rx_dma_addr[i] = 0;
     }
 
-    for (i = 0; i < TX_RING_SIZE; i++) {
+    for (i = 0; i < lp->tx_ring_size; i++) {
 	lp->tx_ring[i].status = 0;	/* CPU owns buffer */
 	wmb();		/* Make sure adapter sees owner change */
 	if (lp->tx_skbuff[i]) {
@@ -2267,6 +2420,7 @@ static void __devexit pcnet32_remove_one
 	struct pcnet32_private *lp = dev->priv;
 
 	unregister_netdev(dev);
+	pcnet32_free_ring(dev);
 	release_region(dev->base_addr, PCNET32_TOTAL_SIZE);
 	pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
 	free_netdev(dev);
@@ -2342,6 +2496,7 @@ static void __exit pcnet32_cleanup_modul
 	struct pcnet32_private *lp = pcnet32_dev->priv;
 	next_dev = lp->next;
 	unregister_netdev(pcnet32_dev);
+	pcnet32_free_ring(pcnet32_dev);
 	release_region(pcnet32_dev->base_addr, PCNET32_TOTAL_SIZE);
 	pci_free_consistent(lp->pci_dev, sizeof(*lp), lp, lp->dma_addr);
 	free_netdev(pcnet32_dev);
---
0.99.8.GIT


--- NEW FILE 0100-pcnet32-set-min-ring-size-to-4.txt ---
Subject: [PATCH] pcnet32: set min ring size to 4
From: Hubert WS Lin <wslin at tw.ibm.com>
Date: 1126723167 -0700

Don Fry reminded me that the pcnet32_loopback_test() asssumes the ring size
is no less than 4.  The minimum ring size was changed to 4 in
pcnet32_set_ringparam() to allow the loopback test to work unchanged.

- Set minimum ring size to 4 to allow loopback test to work unchanged
- Moved variable init_block to first field in struct pcnet32_private

Signed-off-by: Hubert WS Lin <wslin at tw.ibm.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/pcnet32.c |   19 ++++++++++++-------
 1 files changed, 12 insertions(+), 7 deletions(-)

applies-to: 82e41403e8b3f0dbf8f4a47bd90a5afc57142e36
76209926e3756f66c9cdc8a4becbf34df8c47799
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 7350c27..70fe81a 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -22,8 +22,8 @@
  *************************************************************************/
 
 #define DRV_NAME	"pcnet32"
-#define DRV_VERSION	"1.31"
-#define DRV_RELDATE	"02.Sep.2005"
+#define DRV_VERSION	"1.31a"
+#define DRV_RELDATE	"12.Sep.2005"
 #define PFX		DRV_NAME ": "
 
 static const char *version =
@@ -258,6 +258,8 @@ static int homepna[MAX_UNITS];
  * v1.30i  28 Jun 2004 Don Fry change to use module_param.
  * v1.30j  29 Apr 2005 Don Fry fix skb/map leak with loopback test.
  * v1.31   02 Sep 2005 Hubert WS Lin <wslin at tw.ibm.c0m> added set_ringparam().
+ * v1.31a  12 Sep 2005 Hubert WS Lin <wslin at tw.ibm.c0m> set min ring size to 4
+ *	   to allow loopback test to work unchanged.
  */
 
 
@@ -335,14 +337,14 @@ struct pcnet32_access {
 };
 
 /*
- * The first three fields of pcnet32_private are read by the ethernet device
- * so we allocate the structure should be allocated by pci_alloc_consistent().
+ * The first field of pcnet32_private is read by the ethernet device
+ * so the structure should be allocated using pci_alloc_consistent().
  */
 struct pcnet32_private {
+    struct pcnet32_init_block init_block;
     /* The Tx and Rx ring entries must be aligned on 16-byte boundaries in 32bit mode. */
     struct pcnet32_rx_head    *rx_ring;
     struct pcnet32_tx_head    *tx_ring;
-    struct pcnet32_init_block init_block;
     dma_addr_t		dma_addr;	/* DMA address of beginning of this
 					   object, returned by
 					   pci_alloc_consistent */
@@ -648,7 +650,10 @@ static int pcnet32_set_ringparam(struct 
     lp->tx_ring_size = min(ering->tx_pending, (unsigned int) TX_MAX_RING_SIZE);
     lp->rx_ring_size = min(ering->rx_pending, (unsigned int) RX_MAX_RING_SIZE);
 
-    for (i = 0; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
+    /* set the minimum ring size to 4, to allow the loopback test to work
+     * unchanged.
+     */
+    for (i = 2; i <= PCNET32_LOG_MAX_TX_BUFFERS; i++) {
 	if (lp->tx_ring_size <= (1 << i))
 	    break;
     }
@@ -656,7 +661,7 @@ static int pcnet32_set_ringparam(struct 
     lp->tx_mod_mask = lp->tx_ring_size - 1;
     lp->tx_len_bits = (i << 12);
 
-    for (i = 0; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
+    for (i = 2; i <= PCNET32_LOG_MAX_RX_BUFFERS; i++) {
 	if (lp->rx_ring_size <= (1 << i))
 	    break;
     }
---
0.99.8.GIT


--- NEW FILE 0101-orinoco-Remove-conditionals-that-are-useless-in-the-kernel-drivers.txt ---
Subject: [PATCH] orinoco: Remove conditionals that are useless in the kernel drivers.
From: Pavel Roskin <proski at gnu.org>
Date: 1126851313 -0400

Author: Pavel Roskin <proski at gnu.org>
Date:   Fri Sep 16 00:49:05 2005 -0400

    Remove conditionals that are useless in the kernel drivers.

    Kernel drivers are never compiled against pcmcia-cs headers.
    Firmware is never embedded into spectrum_cs module.

Signed-off-by: Pavel Roskin <proski at gnu.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco_cs.c  |    3 ---
 drivers/net/wireless/spectrum_cs.c |   26 +-------------------------
 2 files changed, 1 insertions(+), 28 deletions(-)

applies-to: 173b55358f0864026fe9957407409f8613448ed4
65853b133d0256786df25f03eea0e5a6799e8d17
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index bedd7f9..1cedabf 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -14,9 +14,6 @@
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-#ifdef  __IN_PCMCIA_PACKAGE__
-#include <pcmcia/k_compat.h>
-#endif /* __IN_PCMCIA_PACKAGE__ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 39c6cdf..256d31b 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -22,9 +22,6 @@
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-#ifdef  __IN_PCMCIA_PACKAGE__
-#include <pcmcia/k_compat.h>
-#endif /* __IN_PCMCIA_PACKAGE__ */
 
 #include <linux/module.h>
 #include <linux/kernel.h>
@@ -38,6 +35,7 @@
 #include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/wireless.h>
+#include <linux/firmware.h>
 
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
@@ -51,29 +49,10 @@
 
 #include "orinoco.h"
 
-/*
- * If SPECTRUM_FW_INCLUDED is defined, the firmware is hardcoded into
- * the driver.  Use get_symbol_fw script to generate spectrum_fw.h and
- * copy it to the same directory as spectrum_cs.c.
- *
- * If SPECTRUM_FW_INCLUDED is not defined, the firmware is loaded at the
- * runtime using hotplug.  Use the same get_symbol_fw script to generate
- * files symbol_sp24t_prim_fw symbol_sp24t_sec_fw, copy them to the
- * hotplug firmware directory (typically /usr/lib/hotplug/firmware) and
- * make sure that you have hotplug installed and enabled in the kernel.
- */
-/* #define SPECTRUM_FW_INCLUDED 1 */
-
-#ifdef SPECTRUM_FW_INCLUDED
-/* Header with the firmware */
-#include "spectrum_fw.h"
-#else	/* !SPECTRUM_FW_INCLUDED */
-#include <linux/firmware.h>
 static unsigned char *primsym;
 static unsigned char *secsym;
 static const char primary_fw_name[] = "symbol_sp24t_prim_fw";
 static const char secondary_fw_name[] = "symbol_sp24t_sec_fw";
-#endif	/* !SPECTRUM_FW_INCLUDED */
 
 /********************************************************************/
 /* Module stuff							    */
@@ -571,8 +550,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_l
 {
 	int ret;
 	client_handle_t handle = link->handle;
-
-#ifndef SPECTRUM_FW_INCLUDED
 	const struct firmware *fw_entry;
 
 	if (request_firmware(&fw_entry, primary_fw_name,
@@ -592,7 +569,6 @@ spectrum_dl_firmware(hermes_t *hw, dev_l
 		       secondary_fw_name);
 		return -ENOENT;
 	}
-#endif
 
 	/* Load primary firmware */
 	ret = spectrum_dl_image(hw, link, primsym);
---
0.99.8.GIT


--- NEW FILE 0102-orinoco-Don-t-include-net-ieee80211.h-twice.txt ---
Subject: [PATCH] orinoco: Don't include <net/ieee80211.h> twice.
From: Pavel Roskin <proski at gnu.org>
Date: 1126851412 -0400

Author: Pavel Roskin <proski at gnu.org>
Date:   Fri Sep 16 00:50:00 2005 -0400

    Don't include <net/ieee80211.h> twice.

Signed-off-by: Pavel Roskin <proski at gnu.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

applies-to: 38c3d8007e70992829271a2fcf453624d4afadd2
27c91efba4c121f90c0e6d371c7064733b286a69
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 639b8e4..77e93a2 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -94,8 +94,6 @@
 #include <net/iw_handler.h>
 #include <net/ieee80211.h>
 
-#include <net/ieee80211.h>
-
 #include <asm/uaccess.h>
 #include <asm/io.h>
 #include <asm/system.h>
---
0.99.8.GIT


--- NEW FILE 0103-orinoco-Update-PCMCIA-ID-s.txt ---
Subject: [PATCH] orinoco: Update PCMCIA ID's.
From: Pavel Roskin <proski at gnu.org>
Date: 1126851511 -0400

Author: Pavel Roskin <proski at gnu.org>
Date:   Fri Sep 16 01:07:47 2005 -0400

    Update PCMCIA ID's.

    Intel Pro/Wireless 2011 and 2011B have the same numeric ID, so use
    strings instead.

    Take all entries from *.conf for Orinoco, HostAP and linux-wlan-ng and
    adds them with minimal changes (e.g. we don't need a revision string
    after a string that identifies the chipset).

    Add comments with card names to all numeric entries.  Note: the comments
    don't and cannot cover all cards, since the main reason of having
    numeric IDs is to cover cards that are often rebranded.

Signed-off-by: Pavel Roskin <proski at gnu.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco_cs.c  |   76 +++++++++++++++++++++++++++---------
 drivers/net/wireless/spectrum_cs.c |    2 -
 2 files changed, 57 insertions(+), 21 deletions(-)

applies-to: 78dd96949dcb026a37f182255db3d804a4274706
9c8a11d7c2298680ff3ee8acda54575c88668bfc
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 1cedabf..80920b1 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -600,49 +600,85 @@ static char version[] __initdata = DRIVE
 	"Pavel Roskin <proski at gnu.org>, et al)";
 
 static struct pcmcia_device_id orinoco_cs_ids[] = {
-	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300),
-	PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002),
-	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002),
-	PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a),
-	PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002),
-	PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001),
-	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305),
-	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613),
-	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002),
-	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673),
-	PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002),
-	PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002),
-	PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001),
-	PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300),
-	PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021),
-	PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002),
-	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002),
-	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005),
+	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7100), /* SonicWALL Long Range Wireless Card */
+	PCMCIA_DEVICE_MANF_CARD(0x000b, 0x7300), /* Sohoware NCP110, Philips 802.11b */
+	PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0002), /* AnyPoint(TM) Wireless II PC Card */
+	PCMCIA_DEVICE_MANF_CARD(0x0101, 0x0777), /* 3Com AirConnect PCI 777A */
+	PCMCIA_DEVICE_MANF_CARD(0x0126, 0x8000), /* PROXIM RangeLAN-DS/LAN PC CARD */
+	PCMCIA_DEVICE_MANF_CARD(0x0138, 0x0002), /* Compaq WL100 11 Mbps Wireless Adapter */
+	PCMCIA_DEVICE_MANF_CARD(0x0156, 0x0002), /* Lucent Orinoco and old Intersil */
+	PCMCIA_DEVICE_MANF_CARD(0x016b, 0x0001), /* Ericsson WLAN Card C11 */
+	PCMCIA_DEVICE_MANF_CARD(0x01eb, 0x080a), /* Nortel Networks eMobility 802.11 Wireless Adapter */
+	PCMCIA_DEVICE_MANF_CARD(0x01ff, 0x0008), /* Intermec MobileLAN 11Mbps 802.11b WLAN Card */
+	PCMCIA_DEVICE_MANF_CARD(0x0250, 0x0002), /* Samsung SWL2000-N 11Mb/s WLAN Card */
+	PCMCIA_DEVICE_MANF_CARD(0x0261, 0x0002), /* AirWay 802.11 Adapter (PCMCIA) */
+	PCMCIA_DEVICE_MANF_CARD(0x0268, 0x0001), /* ARtem Onair */
+	PCMCIA_DEVICE_MANF_CARD(0x026f, 0x0305), /* Buffalo WLI-PCM-S11 */
+	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1612), /* Linksys WPC11 Version 2.5 */
+	PCMCIA_DEVICE_MANF_CARD(0x0274, 0x1613), /* Linksys WPC11 Version 3 */
+	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0002), /* Compaq HNW-100 11 Mbps Wireless Adapter */
+	PCMCIA_DEVICE_MANF_CARD(0x028a, 0x0673), /* Linksys WCF12 Wireless CompactFlash Card */
+	PCMCIA_DEVICE_MANF_CARD(0x02aa, 0x0002), /* ASUS SpaceLink WL-100 */
+	PCMCIA_DEVICE_MANF_CARD(0x02ac, 0x0002), /* SpeedStream SS1021 Wireless Adapter */
+	PCMCIA_DEVICE_MANF_CARD(0x14ea, 0xb001), /* PLANEX RoadLannerWave GW-NS11H */
+	PCMCIA_DEVICE_MANF_CARD(0x50c2, 0x7300), /* Airvast WN-100 */
+	PCMCIA_DEVICE_MANF_CARD(0x9005, 0x0021), /* Adaptec Ultra Wireless ANW-8030 */
+	PCMCIA_DEVICE_MANF_CARD(0xc001, 0x0008), /* CONTEC FLEXSCAN/FX-DDS110-PCC */
+	PCMCIA_DEVICE_MANF_CARD(0xc250, 0x0002), /* Conceptronic CON11Cpro, EMTAC A2424i */
+	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0002), /* Safeway 802.11b, ZCOMAX AirRunner/XI-300 */
+	PCMCIA_DEVICE_MANF_CARD(0xd601, 0x0005), /* D-Link DCF660, Sandisk Connect SDWCFB-000 */
+	PCMCIA_DEVICE_PROD_ID12(" ", "IEEE 802.11 Wireless LAN/PC Card", 0x3b6e20c8, 0xefccafe9),
 	PCMCIA_DEVICE_PROD_ID12("3Com", "3CRWE737A AirConnect Wireless LAN PC Card", 0x41240e5b, 0x56010af3),
-	PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
 	PCMCIA_DEVICE_PROD_ID12("ACTIONTEC", "PRISM Wireless LAN PC Card", 0x393089da, 0xa71e69d5),
+	PCMCIA_DEVICE_PROD_ID12("Addtron", "AWP-100 Wireless PCMCIA", 0xe6ec52ce, 0x08649af2),
+	PCMCIA_DEVICE_PROD_ID123("AIRVAST", "IEEE 802.11b Wireless PCMCIA Card", "HFA3863", 0xea569531, 0x4bcb9645, 0x355cb092),
+	PCMCIA_DEVICE_PROD_ID12("Allied Telesyn", "AT-WCL452 Wireless PCMCIA Radio", 0x5cd01705, 0x4271660f),
+	PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11b_PC_CARD_25", 0x78fc06ee, 0xdb9aa842),
+	PCMCIA_DEVICE_PROD_ID12("ASUS", "802_11B_CF_CARD_25", 0x78fc06ee, 0x45a50c1e),
 	PCMCIA_DEVICE_PROD_ID12("Avaya Communication", "Avaya Wireless PC Card", 0xd8a43b78, 0x0d341169),
+	PCMCIA_DEVICE_PROD_ID12("BENQ", "AWL100 PCMCIA ADAPTER", 0x35dadc74, 0x01f7fedb),
 	PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-PCM-L11G", 0x2decece3, 0xf57ca4b3),
+	PCMCIA_DEVICE_PROD_ID12("BUFFALO", "WLI-CF-S11G", 0x2decece3, 0x82067c18),
 	PCMCIA_DEVICE_PROD_ID12("Cabletron", "RoamAbout 802.11 DS", 0x32d445f5, 0xedeffd90),
+	PCMCIA_DEVICE_PROD_ID12("Compaq", "WL200_11Mbps_Wireless_PCI_Card", 0x54f7c49c, 0x15a75e5b),
+	PCMCIA_DEVICE_PROD_ID123("corega", "WL PCCL-11", "ISL37300P", 0x0a21501a, 0x59868926, 0xc9049a39),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCC-11", 0x5261440f, 0xa6405584),
 	PCMCIA_DEVICE_PROD_ID12("corega K.K.", "Wireless LAN PCCA-11", 0x5261440f, 0xdf6115f9),
 	PCMCIA_DEVICE_PROD_ID12("corega_K.K.", "Wireless_LAN_PCCB-11", 0x29e33311, 0xee7a27ae),
 	PCMCIA_DEVICE_PROD_ID12("D", "Link DRC-650 11Mbps WLAN Card", 0x71b18589, 0xf144e3ac),
 	PCMCIA_DEVICE_PROD_ID12("D", "Link DWL-650 11Mbps WLAN Card", 0x71b18589, 0xb6f1b0ab),
+	PCMCIA_DEVICE_PROD_ID12("D-Link Corporation", "D-Link DWL-650H 11Mbps WLAN Adapter", 0xef544d24, 0xcd8ea916),
+	PCMCIA_DEVICE_PROD_ID12("Digital Data Communications", "WPC-0100", 0xfdd73470, 0xe0b6f146),
 	PCMCIA_DEVICE_PROD_ID12("ELSA", "AirLancer MC-11", 0x4507a33a, 0xef54f0e3),
 	PCMCIA_DEVICE_PROD_ID12("HyperLink", "Wireless PC Card 11Mbps", 0x56cc3f1a, 0x0bcf220c),
+	PCMCIA_DEVICE_PROD_ID123("Instant Wireless ", " Network PC CARD", "Version 01.02", 0x11d901af, 0x6e9bd926, 0x4b74baa0),
+	PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless 2011 LAN PC Card", 0x816cc815, 0x07f58077),
 	PCMCIA_DEVICE_PROD_ID12("INTERSIL", "HFA384x/IEEE", 0x74c5e40d, 0xdb472a18),
+	PCMCIA_DEVICE_PROD_ID12("INTERSIL", "I-GATE 11M PC Card / PC Card plus", 0x74c5e40d, 0x8304ff77),
+	PCMCIA_DEVICE_PROD_ID12("Intersil", "PRISM 2_5 PCMCIA ADAPTER", 0x4b801a17, 0x6345a0bf),
+	PCMCIA_DEVICE_PROD_ID123("Intersil", "PRISM Freedom PCMCIA Adapter", "ISL37100P", 0x4b801a17, 0xf222ec2d, 0x630d52b2),
+	PCMCIA_DEVICE_PROD_ID12("LeArtery", "SYNCBYAIR 11Mbps Wireless LAN PC Card", 0x7e3b326a, 0x49893e92),
+	PCMCIA_DEVICE_PROD_ID12("Linksys", "Wireless CompactFlash Card", 0x0733cc81, 0x0c52f395),
 	PCMCIA_DEVICE_PROD_ID12("Lucent Technologies", "WaveLAN/IEEE", 0x23eb9949, 0xc562e72a),
 	PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11", 0x481e0094, 0x7360e410),
 	PCMCIA_DEVICE_PROD_ID12("MELCO", "WLI-PCM-L11G", 0x481e0094, 0xf57ca4b3),
 	PCMCIA_DEVICE_PROD_ID12("Microsoft", "Wireless Notebook Adapter MN-520", 0x5961bf85, 0x6eec8c01),
 	PCMCIA_DEVICE_PROD_ID12("NCR", "WaveLAN/IEEE", 0x24358cd4, 0xc562e72a),
+	PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401 Wireless PC", "Card", 0xa37434e9, 0x9762e8f1),
 	PCMCIA_DEVICE_PROD_ID12("NETGEAR MA401RA Wireless PC", "Card", 0x0306467f, 0x9762e8f1),
+	PCMCIA_DEVICE_PROD_ID12("Nortel Networks", "emobility 802.11 Wireless LAN PC Card", 0x2d617ea0, 0x88cd5767),
+	PCMCIA_DEVICE_PROD_ID12("OEM", "PRISM2 IEEE 802.11 PC-Card", 0xfea54c90, 0x48f2bdd6),
+	PCMCIA_DEVICE_PROD_ID12("OTC", "Wireless AirEZY 2411-PCC WLAN Card", 0x4ac44287, 0x235a6bed),
+	PCMCIA_DEVICE_PROD_ID123("PCMCIA", "11M WLAN Card v2.5", "ISL37300P", 0x281f1c5d, 0x6e440487, 0xc9049a39),
 	PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-CF110", 0x209f40ab, 0xd9715264),
+	PCMCIA_DEVICE_PROD_ID12("PLANEX", "GeoWave/GW-NS110", 0x209f40ab, 0x46263178),
 	PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PC CARD HARMONY 80211B", 0xc6536a5e, 0x090c3cd9),
 	PCMCIA_DEVICE_PROD_ID12("PROXIM", "LAN PCI CARD HARMONY 80211B", 0xc6536a5e, 0x9f494e26),
 	PCMCIA_DEVICE_PROD_ID12("SAMSUNG", "11Mbps WLAN Card", 0x43d74cb4, 0x579bd91b),
-	PCMCIA_DEVICE_PROD_ID1("Symbol Technologies", 0x3f02b4d6),
+	PCMCIA_DEVICE_PROD_ID12("SMC", "SMC2632W", 0xc4f8b18b, 0x474a1f2a),
+	PCMCIA_DEVICE_PROD_ID12("Symbol Technologies", "LA4111 Spectrum24 Wireless LAN PC Card", 0x3f02b4d6, 0x3663cb0e),
+	PCMCIA_DEVICE_PROD_ID123("The Linksys Group, Inc.", "Instant Wireless Network PC Card", "ISL37300P", 0xa5f472c2, 0x590eb502, 0xc9049a39),
+	PCMCIA_DEVICE_PROD_ID12("ZoomAir 11Mbps High", "Rate wireless Networking", 0x273fe3db, 0x32a1eaee),
 	PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, orinoco_cs_ids);
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 256d31b..63e0042 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -1061,7 +1061,7 @@ static char version[] __initdata = DRIVE
 static struct pcmcia_device_id spectrum_cs_ids[] = {
 	PCMCIA_DEVICE_MANF_CARD(0x026c, 0x0001), /* Symbol Spectrum24 LA4100 */
 	PCMCIA_DEVICE_MANF_CARD(0x0104, 0x0001), /* Socket Communications CF */
-	PCMCIA_DEVICE_MANF_CARD(0x0089, 0x0001), /* Intel PRO/Wireless 2011B */
+	PCMCIA_DEVICE_PROD_ID12("Intel", "PRO/Wireless LAN PC Card", 0x816cc815, 0x6fbf459a), /* 2011B, not 2011 */
 	PCMCIA_DEVICE_NULL,
 };
 MODULE_DEVICE_TABLE(pcmcia, spectrum_cs_ids);
---
0.99.8.GIT


--- NEW FILE 0112-Updated-ipw2200-to-compile-with-ieee80211-abg_ture-to-abg_true-change.txt ---
Subject: [PATCH] Updated ipw2200 to compile with ieee80211 abg_ture to abg_true change
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1126726139 -0500

author James Ketrenos <jketreno at linux.intel.com> 1126713327 -0500
committer James Ketrenos <jketreno at linux.intel.com> 1126713327 -0500

Updated ipw2200 to compile with ieee80211 abg_ture to abg_true change.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/ipw2200.c |   14 +++++++-------
 1 files changed, 7 insertions(+), 7 deletions(-)

applies-to: fec657fe7a87aedc5a60e5c1128c6ba509ae18f8
a33a1982012e9070736e3717231714dc9892303b
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index b7f275c..86feef7 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -6010,12 +6010,12 @@ static int ipw_wx_set_wireless_mode(stru
 	}
 
 	if (priv->adapter == IPW_2915ABG) {
-		priv->ieee->abg_ture = 1;
+		priv->ieee->abg_true = 1;
 		if (mode & IEEE_A) {
 			band |= IEEE80211_52GHZ_BAND;
 			modulation |= IEEE80211_OFDM_MODULATION;
 		} else
-			priv->ieee->abg_ture = 0;
+			priv->ieee->abg_true = 0;
 	} else {
 		if (mode & IEEE_A) {
 			IPW_WARNING("Attempt to set 2200BG into "
@@ -6023,20 +6023,20 @@ static int ipw_wx_set_wireless_mode(stru
 			return -EINVAL;
 		}
 
-		priv->ieee->abg_ture = 0;
+		priv->ieee->abg_true = 0;
 	}
 
 	if (mode & IEEE_B) {
 		band |= IEEE80211_24GHZ_BAND;
 		modulation |= IEEE80211_CCK_MODULATION;
 	} else
-		priv->ieee->abg_ture = 0;
+		priv->ieee->abg_true = 0;
 
 	if (mode & IEEE_G) {
 		band |= IEEE80211_24GHZ_BAND;
 		modulation |= IEEE80211_OFDM_MODULATION;
 	} else
-		priv->ieee->abg_ture = 0;
+		priv->ieee->abg_true = 0;
 
 	priv->ieee->mode = mode;
 	priv->ieee->freq_band = band;
@@ -7108,7 +7108,7 @@ static int ipw_pci_probe(struct pci_dev 
 		printk(KERN_INFO DRV_NAME
 		       ": Detected Intel PRO/Wireless 2915ABG Network "
 		       "Connection\n");
-		priv->ieee->abg_ture = 1;
+		priv->ieee->abg_true = 1;
 		band = IEEE80211_52GHZ_BAND | IEEE80211_24GHZ_BAND;
 		modulation = IEEE80211_OFDM_MODULATION |
 		    IEEE80211_CCK_MODULATION;
@@ -7124,7 +7124,7 @@ static int ipw_pci_probe(struct pci_dev 
 			       ": Detected Intel PRO/Wireless 2200BG Network "
 			       "Connection\n");
 
-		priv->ieee->abg_ture = 0;
+		priv->ieee->abg_true = 0;
 		band = IEEE80211_24GHZ_BAND;
 		modulation = IEEE80211_OFDM_MODULATION |
 		    IEEE80211_CCK_MODULATION;
---
0.99.8.GIT


--- NEW FILE 0161-ieee80211-Updated-ipw2100-to-be-compatible-with-ieee80211_hdr-changes.txt ---
Subject: [PATCH] ieee80211: Updated ipw2100 to be compatible with ieee80211_hdr changes
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1127323405 -0500

tree 992b203395c50342f1cced415acae6177344e270
parent c59bb604a2ff4e40232ff0422e7adc44e3b007a0
author James Ketrenos <jketreno at linux.intel.com> 1126714006 -0500
committer James Ketrenos <jketreno at linux.intel.com> 1127315910 -0500

Updated ipw2100 to be compatible with ieee80211_hdr changes.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/ipw2100.c |    4 ++--
 drivers/net/wireless/ipw2100.h |    2 +-
 2 files changed, 3 insertions(+), 3 deletions(-)

applies-to: 92c26ea74c0ffb9b83a2285ad2539cc271b09856
99a4b232b6682a847c70d877e4a3c15e9138c8f6
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index e5cdb5b..8dc80f8 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -2948,7 +2948,7 @@ static void ipw2100_tx_send_data(struct 
 	int next = txq->next;
         int i = 0;
 	struct ipw2100_data_header *ipw_hdr;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_3addr *hdr;
 
 	while (!list_empty(&priv->tx_pend_list)) {
 		/* if there isn't enough space in TBD queue, then
@@ -2984,7 +2984,7 @@ static void ipw2100_tx_send_data(struct 
 		packet->index = txq->next;
 
 		ipw_hdr = packet->info.d_struct.data;
-		hdr = (struct ieee80211_hdr *)packet->info.d_struct.txb->
+		hdr = (struct ieee80211_hdr_3addr *)packet->info.d_struct.txb->
 			fragments[0]->data;
 
 		if (priv->ieee->iw_mode == IW_MODE_INFRA) {
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 2a3cdbd..c9e99ce 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -808,7 +808,7 @@ struct ipw2100_priv {
 struct ipw2100_rx {
 	union {
 		unsigned char payload[IPW_RX_NIC_BUFFER_LENGTH];
-		struct ieee80211_hdr header;
+		struct ieee80211_hdr_4addr header;
 		u32 status;
 		struct ipw2100_notification notification;
 		struct ipw2100_cmd_header command;
---
0.99.8.GIT


--- NEW FILE 0162-ieee80211-Updated-ipw2100-to-be-compatible-with-ieee80211-s-hard_start_xmit-change.txt ---
Subject: [PATCH] ieee80211: Updated ipw2100 to be compatible with ieee80211's hard_start_xmit change
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1127323417 -0500

tree ee48cbe413b795d6be454b9baf4f3bd3d74814cb
parent 49856b147763bd6847e0d8f53aee1ddd61385638
author James Ketrenos <jketreno at linux.intel.com> 1126716634 -0500
committer James Ketrenos <jketreno at linux.intel.com> 1127316024 -0500

Updated ipw2100 to be compatible with ieee80211's hard_start_xmit change.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/ipw2100.c |    3 ++-
 1 files changed, 2 insertions(+), 1 deletions(-)

applies-to: 7dacb727771de8dc9318beb81752f3c5f22adab2
3a5becf720d6346ffca2d6be6473f603b39322a2
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 8dc80f8..ad7f8cd 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -3269,7 +3269,8 @@ static irqreturn_t ipw2100_interrupt(int
 	return IRQ_NONE;
 }
 
-static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev)
+static int ipw2100_tx(struct ieee80211_txb *txb, struct net_device *dev,
+		      int pri)
 {
 	struct ipw2100_priv *priv = ieee80211_priv(dev);
 	struct list_head *element;
---
0.99.8.GIT


--- NEW FILE 0163-ieee80211-Updated-ipw2200-to-be-compatible-with-ieee80211_hdr-changes.txt ---
Subject: [PATCH] ieee80211: Updated ipw2200 to be compatible with ieee80211_hdr changes
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1127323421 -0500

tree 9f86c7b4f59249c05c96c360dfaa817995e8a44f
parent 9b09701b2c6254f2fddb009004a14eb5a908714f
author James Ketrenos <jketreno at linux.intel.com> 1126714305 -0500
committer James Ketrenos <jketreno at linux.intel.com> 1127316074 -0500

Updated ipw2200 to be compatible with ieee80211_hdr changes.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/ipw2200.c |    9 +++++----
 drivers/net/wireless/ipw2200.h |    4 ++--
 2 files changed, 7 insertions(+), 6 deletions(-)

applies-to: 0084320b04b04b2d61e4630505803104251205a6
0dacca1f0a53938dd7d5ba35c692bd1a3356d504
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 86feef7..34f0052 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -4904,7 +4904,7 @@ static void ipw_rx(struct ipw_priv *priv
 {
 	struct ipw_rx_mem_buffer *rxb;
 	struct ipw_rx_packet *pkt;
-	struct ieee80211_hdr *header;
+	struct ieee80211_hdr_4addr *header;
 	u32 r, w, i;
 	u8 network_packet;
 
@@ -4967,8 +4967,9 @@ static void ipw_rx(struct ipw_priv *priv
 #endif
 
 				header =
-				    (struct ieee80211_hdr *)(rxb->skb->data +
-							     IPW_RX_FRAME_SIZE);
+				    (struct ieee80211_hdr_4addr *)(rxb->skb->
+								   data +
+								   IPW_RX_FRAME_SIZE);
 				/* TODO: Check Ad-Hoc dest/source and make sure
 				 * that we are actually parsing these packets
 				 * correctly -- we should probably use the
@@ -6325,7 +6326,7 @@ we need to heavily modify the ieee80211_
 
 static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb)
 {
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)
+	struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
 	    txb->fragments[0]->data;
 	int i = 0;
 	struct tfd_frame *tfd;
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 5b00882..e9cf32b 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1654,12 +1654,12 @@ static const long ipw_frequencies[] = {
 
 #define IPW_MAX_CONFIG_RETRIES 10
 
-static inline u32 frame_hdr_len(struct ieee80211_hdr *hdr)
+static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
 {
 	u32 retval;
 	u16 fc;
 
-	retval = sizeof(struct ieee80211_hdr);
+	retval = sizeof(struct ieee80211_hdr_3addr);
 	fc = le16_to_cpu(hdr->frame_ctl);
 
 	/*
---
0.99.8.GIT


--- NEW FILE 0164-ieee80211-Updated-ipw2200-to-be-compatible-with-ieee80211-s-hard_start_xmit-change.txt ---
Subject: [PATCH] ieee80211: Updated ipw2200 to be compatible with ieee80211's hard_start_xmit change.
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1127323423 -0500

tree 713b6ff3311decfe42d5209f7b2508736d144b85
parent 6465beff0e89779330450dffc2a5e6dc5154eebf
author James Ketrenos <jketreno at linux.intel.com> 1126716726 -0500
committer James Ketrenos <jketreno at linux.intel.com> 1127316162 -0500

Updated ipw2200 to be compatible with ieee80211's hard_start_xmit change.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/ipw2200.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 1c3e6ddedd1032ef26a4e0f45e8d3b1fa3fd8d96
c8d42d1ae4518091a20f7212b0591a0f4b0e8ca0
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 34f0052..7ea9bd5 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -6449,7 +6449,7 @@ static inline void ipw_tx_skb(struct ipw
 }
 
 static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
-				   struct net_device *dev)
+				   struct net_device *dev, int pri)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	unsigned long flags;
---
0.99.8.GIT


--- NEW FILE 0165-ieee80211-Updated-atmel-to-be-compatible-with-ieee80211_hdr-changes.txt ---
Subject: [PATCH] ieee80211: Updated atmel to be compatible with ieee80211_hdr changes
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1127323426 -0500

tree d7be83000b058b14450d76f99c432b1fb2a1c177
parent 322201093e03830fceedfc24931420b1ea855a8c
author James Ketrenos <jketreno at linux.intel.com> 1127316330 -0500
committer James Ketrenos <jketreno at linux.intel.com> 1127316330 -0500

Updated atmel to be compatible with ieee80211_hdr changes.

Change accomplished via:

sed -i -e "s:ieee80211_hdr\([^_]\):ieee80211_hdr_4addr\1:g" \
	drivers/net/wireless/atmel.c

Compile tested only.

CC: simon at thekelleys.org.uk

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/atmel.c |   24 ++++++++++++------------
 1 files changed, 12 insertions(+), 12 deletions(-)

applies-to: c79676c91d5f8fc12b7ef54625e1bcff8bdab14f
4ca5253d573d7b3785dbb2f123f948fdca6ee235
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 587869d..d570110 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -618,12 +618,12 @@ static int atmel_lock_mac(struct atmel_p
 static void atmel_wmem32(struct atmel_private *priv, u16 pos, u32 data);
 static void atmel_command_irq(struct atmel_private *priv);
 static int atmel_validate_channel(struct atmel_private *priv, int channel);
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header, 
+static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
 				   u16 frame_len, u8 rssi);
 static void atmel_management_timer(u_long a);
 static void atmel_send_command(struct atmel_private *priv, int command, void *cmd, int cmd_size);
 static int atmel_send_command_wait(struct atmel_private *priv, int command, void *cmd, int cmd_size);
-static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void atmel_transmit_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
 					    u8 *body, int body_len);
 
 static u8 atmel_get_mib8(struct atmel_private *priv, u8 type, u8 index);
@@ -827,7 +827,7 @@ static void tx_update_descriptor(struct 
 static int start_tx (struct sk_buff *skb, struct net_device *dev)
 {
 	struct atmel_private *priv = netdev_priv(dev);
-	struct ieee80211_hdr header;
+	struct ieee80211_hdr_4addr header;
 	unsigned long flags;
 	u16 buff, frame_ctl, len = (ETH_ZLEN < skb->len) ? skb->len : ETH_ZLEN;
 	u8 SNAP_RFC1024[6] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
@@ -902,7 +902,7 @@ static int start_tx (struct sk_buff *skb
 }
 
 static void atmel_transmit_management_frame(struct atmel_private *priv, 
-					    struct ieee80211_hdr *header,
+					    struct ieee80211_hdr_4addr *header,
 					    u8 *body, int body_len)
 {
 	u16 buff;
@@ -917,7 +917,7 @@ static void atmel_transmit_management_fr
 	tx_update_descriptor(priv, header->addr1[0] & 0x01, len, buff, TX_PACKET_TYPE_MGMT);
 }
 	
-static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header, 
+static void fast_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
 			 u16 msdu_size, u16 rx_packet_loc, u32 crc)
 {
 	/* fast path: unfragmented packet copy directly into skbuf */
@@ -990,7 +990,7 @@ static int probe_crc(struct atmel_privat
 	return (crc ^ 0xffffffff) == netcrc;
 }
 
-static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr *header, 
+static void frag_rx_path(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
 			 u16 msdu_size, u16 rx_packet_loc, u32 crc, u16 seq_no, u8 frag_no, int more_frags)
 {
 	u8 mac4[6]; 
@@ -1082,7 +1082,7 @@ static void frag_rx_path(struct atmel_pr
 static void rx_done_irq(struct atmel_private *priv)
 {
 	int i;
-	struct ieee80211_hdr header;
+	struct ieee80211_hdr_4addr header;
 	
 	for (i = 0; 
 	     atmel_rmem8(priv, atmel_rx(priv, RX_DESC_FLAGS_OFFSET, priv->rx_desc_head)) == RX_DESC_FLAG_VALID &&
@@ -2650,7 +2650,7 @@ static void handle_beacon_probe(struct a
  
 static void send_authentication_request(struct atmel_private *priv, u8 *challenge, int challenge_len)
 {
-	struct ieee80211_hdr header;
+	struct ieee80211_hdr_4addr header;
 	struct auth_body auth;
 	
 	header.frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH); 
@@ -2688,7 +2688,7 @@ static void send_association_request(str
 {
 	u8 *ssid_el_p;
 	int bodysize;
-	struct ieee80211_hdr header;
+	struct ieee80211_hdr_4addr header;
 	struct ass_req_format {
 		u16 capability;
 		u16 listen_interval; 
@@ -2738,7 +2738,7 @@ static void send_association_request(str
 	atmel_transmit_management_frame(priv, &header, (void *)&body, bodysize);
 }
 
-static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr *header)
+static int is_frame_from_current_bss(struct atmel_private *priv, struct ieee80211_hdr_4addr *header)
 {
 	if (le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_FROMDS)
 		return memcmp(header->addr3, priv->CurrentBSSID, 6) == 0;
@@ -2788,7 +2788,7 @@ static int retrieve_bss(struct atmel_pri
 }
 
 
-static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr *header,
+static void store_bss_info(struct atmel_private *priv, struct ieee80211_hdr_4addr *header,
 			   u16 capability, u16 beacon_period, u8 channel, u8 rssi, 
 			   u8 ssid_len, u8 *ssid, int is_beacon)
 {
@@ -3072,7 +3072,7 @@ static void atmel_smooth_qual(struct atm
 }
 
 /* deals with incoming managment frames. */
-static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr *header, 
+static void atmel_management_frame(struct atmel_private *priv, struct ieee80211_hdr_4addr *header, 
 		      u16 frame_len, u8 rssi)
 {
 	u16 subtype;
---
0.99.8.GIT


--- NEW FILE 0186-ieee80211-Updated-hostap-to-be-compatible-with-ieee80211_hdr-changes.txt ---
Subject: [PATCH] ieee80211: Updated hostap to be compatible with ieee80211_hdr changes
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1127323429 -0500

tree 8ec97d9056ceaf0f845ed51175dd842b700baadd
parent 329128457008ace3110c96971addf85a767dd5af
author James Ketrenos <jketreno at linux.intel.com> 1126714484 -0500
committer James Ketrenos <jketreno at linux.intel.com> 1127316636 -0500

Updated hostap to be compatible with ieee80211_hdr changes.

Change accomplished via:

for i in hostap_ap.{c,h} hostap_80211_{t,r}x.c; do
	sed -i -e "s:ieee80211_hdr\([^_]\):ieee80211_hdr_4addr\1:g" \
		drivers/net/wireless/hostap/$i
done

CC: Jouni Malinen <jkmaline at cc.hut.fi>

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap_80211_rx.c |   40 ++++++++-------
 drivers/net/wireless/hostap/hostap_80211_tx.c |   20 ++++----
 drivers/net/wireless/hostap/hostap_ap.c       |   66 +++++++++++++------------
 drivers/net/wireless/hostap/hostap_ap.h       |    6 +-
 4 files changed, 66 insertions(+), 66 deletions(-)

applies-to: f623693884cb482dcbf3c5e3974442ddd31ca6de
d041674d62e1ad565f2fb6d53ae80b31d6656033
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index b050124..42e61c6 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -6,10 +6,10 @@
 void hostap_dump_rx_80211(const char *name, struct sk_buff *skb,
 			  struct hostap_80211_rx_status *rx_stats)
 {
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u16 fc;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
 	printk(KERN_DEBUG "%s: RX signal=%d noise=%d rate=%d len=%d "
 	       "jiffies=%ld\n",
@@ -51,7 +51,7 @@ int prism2_rx_80211(struct net_device *d
 	int hdrlen, phdrlen, head_need, tail_need;
 	u16 fc;
 	int prism_header, ret;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
@@ -70,7 +70,7 @@ int prism2_rx_80211(struct net_device *d
 		phdrlen = 0;
 	}
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 
 	if (type == PRISM2_RX_MGMT && (fc & IEEE80211_FCTL_VERS)) {
@@ -215,7 +215,7 @@ prism2_frag_cache_find(local_info_t *loc
 
 /* Called only as a tasklet (software IRQ) */
 static struct sk_buff *
-prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr *hdr)
+prism2_frag_cache_get(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
 {
 	struct sk_buff *skb = NULL;
 	u16 sc;
@@ -229,7 +229,7 @@ prism2_frag_cache_get(local_info_t *loca
 	if (frag == 0) {
 		/* Reserve enough space to fit maximum frame length */
 		skb = dev_alloc_skb(local->dev->mtu +
-				    sizeof(struct ieee80211_hdr) +
+				    sizeof(struct ieee80211_hdr_4addr) +
 				    8 /* LLC */ +
 				    2 /* alignment */ +
 				    8 /* WEP */ + ETH_ALEN /* WDS */);
@@ -267,7 +267,7 @@ prism2_frag_cache_get(local_info_t *loca
 
 /* Called only as a tasklet (software IRQ) */
 static int prism2_frag_cache_invalidate(local_info_t *local,
-					struct ieee80211_hdr *hdr)
+					struct ieee80211_hdr_4addr *hdr)
 {
 	u16 sc;
 	unsigned int seq;
@@ -441,7 +441,7 @@ hostap_rx_frame_mgmt(local_info_t *local
 		     u16 stype)
 {
 	if (local->iw_mode == IW_MODE_MASTER) {
-		hostap_update_sta_ps(local, (struct ieee80211_hdr *)
+		hostap_update_sta_ps(local, (struct ieee80211_hdr_4addr *)
 				     skb->data);
 	}
 
@@ -520,7 +520,7 @@ static inline struct net_device *prism2_
 
 
 static inline int
-hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr *hdr,
+hostap_rx_frame_wds(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
 		    u16 fc, struct net_device **wds)
 {
 	/* FIX: is this really supposed to accept WDS frames only in Master
@@ -579,13 +579,13 @@ static int hostap_is_eapol_frame(local_i
 {
 	struct net_device *dev = local->dev;
 	u16 fc, ethertype;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u8 *pos;
 
 	if (skb->len < 24)
 		return 0;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 
 	/* check that the frame is unicast frame to us */
@@ -619,13 +619,13 @@ static inline int
 hostap_rx_frame_decrypt(local_info_t *local, struct sk_buff *skb,
 			struct ieee80211_crypt_data *crypt)
 {
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	int res, hdrlen;
 
 	if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
 		return 0;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
 	if (local->tkip_countermeasures &&
@@ -658,13 +658,13 @@ static inline int
 hostap_rx_frame_decrypt_msdu(local_info_t *local, struct sk_buff *skb,
 			     int keyidx, struct ieee80211_crypt_data *crypt)
 {
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	int res, hdrlen;
 
 	if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
 		return 0;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	hdrlen = hostap_80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
 
 	atomic_inc(&crypt->refcnt);
@@ -689,7 +689,7 @@ void hostap_80211_rx(struct net_device *
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	size_t hdrlen;
 	u16 fc, type, stype, sc;
 	struct net_device *wds = NULL;
@@ -716,7 +716,7 @@ void hostap_80211_rx(struct net_device *
 	dev = local->ddev;
 	iface = netdev_priv(dev);
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	stats = hostap_get_stats(dev);
 
 	if (skb->len < 10)
@@ -889,7 +889,7 @@ void hostap_80211_rx(struct net_device *
 	if (local->host_decrypt && (fc & IEEE80211_FCTL_PROTECTED) &&
 	    (keyidx = hostap_rx_frame_decrypt(local, skb, crypt)) < 0)
 		goto rx_dropped;
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
 	/* skb: hdr + (possibly fragmented) plaintext payload */
 
@@ -941,7 +941,7 @@ void hostap_80211_rx(struct net_device *
 		/* this was the last fragment and the frame will be
 		 * delivered, so remove skb from fragment cache */
 		skb = frag_skb;
-		hdr = (struct ieee80211_hdr *) skb->data;
+		hdr = (struct ieee80211_hdr_4addr *) skb->data;
 		prism2_frag_cache_invalidate(local, hdr);
 	}
 
@@ -952,7 +952,7 @@ void hostap_80211_rx(struct net_device *
 	    hostap_rx_frame_decrypt_msdu(local, skb, keyidx, crypt))
 		goto rx_dropped;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	if (crypt && !(fc & IEEE80211_FCTL_PROTECTED) && !local->open_wep) {
 		if (local->ieee_802_1x &&
 		    hostap_is_eapol_frame(local, skb)) {
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 6358015..6db4543 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -1,9 +1,9 @@
 void hostap_dump_tx_80211(const char *name, struct sk_buff *skb)
 {
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u16 fc;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
 	printk(KERN_DEBUG "%s: TX len=%d jiffies=%ld\n",
 	       name, skb->len, jiffies);
@@ -41,7 +41,7 @@ int hostap_data_start_xmit(struct sk_buf
 	struct hostap_interface *iface;
 	local_info_t *local;
 	int need_headroom, need_tailroom = 0;
-	struct ieee80211_hdr hdr;
+	struct ieee80211_hdr_4addr hdr;
 	u16 fc, ethertype = 0;
 	enum {
 		WDS_NO = 0, WDS_OWN_FRAME, WDS_COMPLIANT_FRAME
@@ -244,7 +244,7 @@ int hostap_mgmt_start_xmit(struct sk_buf
 	struct hostap_interface *iface;
 	local_info_t *local;
 	struct hostap_skb_tx_data *meta;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u16 fc;
 
 	iface = netdev_priv(dev);
@@ -266,7 +266,7 @@ int hostap_mgmt_start_xmit(struct sk_buf
 	meta->iface = iface;
 
 	if (skb->len >= IEEE80211_DATA_HDR3_LEN + sizeof(rfc1042_header) + 2) {
-		hdr = (struct ieee80211_hdr *) skb->data;
+		hdr = (struct ieee80211_hdr_4addr *) skb->data;
 		fc = le16_to_cpu(hdr->frame_ctl);
 		if (WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA &&
 		    WLAN_FC_GET_STYPE(fc) == IEEE80211_STYPE_DATA) {
@@ -289,7 +289,7 @@ struct sk_buff * hostap_tx_encrypt(struc
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u16 fc;
 	int hdr_len, res;
 
@@ -303,7 +303,7 @@ struct sk_buff * hostap_tx_encrypt(struc
 
 	if (local->tkip_countermeasures &&
 	    crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
-		hdr = (struct ieee80211_hdr *) skb->data;
+		hdr = (struct ieee80211_hdr_4addr *) skb->data;
 		if (net_ratelimit()) {
 			printk(KERN_DEBUG "%s: TKIP countermeasures: dropped "
 			       "TX packet to " MACSTR "\n",
@@ -325,7 +325,7 @@ struct sk_buff * hostap_tx_encrypt(struc
 		return NULL;
 	}
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
  	fc = le16_to_cpu(hdr->frame_ctl);
 	hdr_len = hostap_80211_get_hdrlen(fc);
 
@@ -360,7 +360,7 @@ int hostap_master_start_xmit(struct sk_b
 	ap_tx_ret tx_ret;
 	struct hostap_skb_tx_data *meta;
 	int no_encrypt = 0;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
@@ -403,7 +403,7 @@ int hostap_master_start_xmit(struct sk_b
 	tx_ret = hostap_handle_sta_tx(local, &tx);
 	skb = tx.skb;
 	meta = (struct hostap_skb_tx_data *) skb->cb;
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
  	fc = le16_to_cpu(hdr->frame_ctl);
 	switch (tx_ret) {
 	case AP_TX_CONTINUE:
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 930cef8..070f703 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -591,14 +591,14 @@ static void hostap_ap_tx_cb(struct sk_bu
 {
 	struct ap_data *ap = data;
 	u16 fc;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
 	if (!ap->local->hostapd || !ap->local->apdev) {
 		dev_kfree_skb(skb);
 		return;
 	}
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 
 	/* Pass the TX callback frame to the hostapd; use 802.11 header version
@@ -623,7 +623,7 @@ static void hostap_ap_tx_cb_auth(struct 
 {
 	struct ap_data *ap = data;
 	struct net_device *dev = ap->local->dev;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u16 fc, *pos, auth_alg, auth_transaction, status;
 	struct sta_info *sta = NULL;
 	char *txt = NULL;
@@ -633,7 +633,7 @@ static void hostap_ap_tx_cb_auth(struct 
 		return;
 	}
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 	if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
 	    WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_AUTH ||
@@ -692,7 +692,7 @@ static void hostap_ap_tx_cb_assoc(struct
 {
 	struct ap_data *ap = data;
 	struct net_device *dev = ap->local->dev;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u16 fc, *pos, status;
 	struct sta_info *sta = NULL;
 	char *txt = NULL;
@@ -702,7 +702,7 @@ static void hostap_ap_tx_cb_assoc(struct
 		return;
 	}
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 	if (WLAN_FC_GET_TYPE(fc) != IEEE80211_FTYPE_MGMT ||
 	    (WLAN_FC_GET_STYPE(fc) != IEEE80211_STYPE_ASSOC_RESP &&
@@ -757,12 +757,12 @@ static void hostap_ap_tx_cb_assoc(struct
 static void hostap_ap_tx_cb_poll(struct sk_buff *skb, int ok, void *data)
 {
 	struct ap_data *ap = data;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	struct sta_info *sta;
 
 	if (skb->len < 24)
 		goto fail;
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	if (ok) {
 		spin_lock(&ap->sta_table_lock);
 		sta = ap_get_sta(ap, hdr->addr1);
@@ -918,7 +918,7 @@ static void prism2_send_mgmt(struct net_
 {
 	struct hostap_interface *iface;
 	local_info_t *local;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	u16 fc;
 	struct sk_buff *skb;
 	struct hostap_skb_tx_data *meta;
@@ -944,7 +944,7 @@ static void prism2_send_mgmt(struct net_
 
 	fc = type_subtype;
 	hdrlen = hostap_80211_get_hdrlen(fc);
-	hdr = (struct ieee80211_hdr *) skb_put(skb, hdrlen);
+	hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, hdrlen);
 	if (body)
 		memcpy(skb_put(skb, body_len), body, body_len);
 
@@ -1285,7 +1285,7 @@ static void handle_authen(local_info_t *
 			  struct hostap_80211_rx_status *rx_stats)
 {
 	struct net_device *dev = local->dev;
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	size_t hdrlen;
 	struct ap_data *ap = local->ap;
 	char body[8 + WLAN_AUTH_CHALLENGE_LEN], *challenge = NULL;
@@ -1498,7 +1498,7 @@ static void handle_assoc(local_info_t *l
 			 struct hostap_80211_rx_status *rx_stats, int reassoc)
 {
 	struct net_device *dev = local->dev;
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	char body[12], *p, *lpos;
 	int len, left;
 	u16 *pos;
@@ -1705,7 +1705,7 @@ static void handle_deauth(local_info_t *
 			  struct hostap_80211_rx_status *rx_stats)
 {
 	struct net_device *dev = local->dev;
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	char *body = (char *) (skb->data + IEEE80211_MGMT_HDR_LEN);
 	int len;
 	u16 reason_code, *pos;
@@ -1746,7 +1746,7 @@ static void handle_disassoc(local_info_t
 			    struct hostap_80211_rx_status *rx_stats)
 {
 	struct net_device *dev = local->dev;
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
 	int len;
 	u16 reason_code, *pos;
@@ -1784,7 +1784,7 @@ static void handle_disassoc(local_info_t
 
 /* Called only as a scheduled task for pending AP frames. */
 static void ap_handle_data_nullfunc(local_info_t *local,
-				    struct ieee80211_hdr *hdr)
+				    struct ieee80211_hdr_4addr *hdr)
 {
 	struct net_device *dev = local->dev;
 
@@ -1801,7 +1801,7 @@ static void ap_handle_data_nullfunc(loca
 
 /* Called only as a scheduled task for pending AP frames. */
 static void ap_handle_dropped_data(local_info_t *local,
-				   struct ieee80211_hdr *hdr)
+				   struct ieee80211_hdr_4addr *hdr)
 {
 	struct net_device *dev = local->dev;
 	struct sta_info *sta;
@@ -1860,7 +1860,7 @@ static void pspoll_send_buffered(local_i
 
 /* Called only as a scheduled task for pending AP frames. */
 static void handle_pspoll(local_info_t *local,
-			  struct ieee80211_hdr *hdr,
+			  struct ieee80211_hdr_4addr *hdr,
 			  struct hostap_80211_rx_status *rx_stats)
 {
 	struct net_device *dev = local->dev;
@@ -1979,7 +1979,7 @@ static void handle_wds_oper_queue(void *
 static void handle_beacon(local_info_t *local, struct sk_buff *skb,
 			  struct hostap_80211_rx_status *rx_stats)
 {
-	struct ieee80211_hdr *hdr = (struct ieee80211_hdr *) skb->data;
+	struct ieee80211_hdr_4addr *hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	char *body = skb->data + IEEE80211_MGMT_HDR_LEN;
 	int len, left;
 	u16 *pos, beacon_int, capability;
@@ -2137,11 +2137,11 @@ static void handle_ap_item(local_info_t 
 	struct net_device *dev = local->dev;
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 	u16 fc, type, stype;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
 	/* FIX: should give skb->len to handler functions and check that the
 	 * buffer is long enough */
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 	type = WLAN_FC_GET_TYPE(fc);
 	stype = WLAN_FC_GET_STYPE(fc);
@@ -2258,7 +2258,7 @@ void hostap_rx(struct net_device *dev, s
 	struct hostap_interface *iface;
 	local_info_t *local;
 	u16 fc;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
@@ -2268,7 +2268,7 @@ void hostap_rx(struct net_device *dev, s
 
 	local->stats.rx_packets++;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	fc = le16_to_cpu(hdr->frame_ctl);
 
 	if (local->ap->ap_policy == AP_OTHER_AP_SKIP_ALL &&
@@ -2289,7 +2289,7 @@ void hostap_rx(struct net_device *dev, s
 static void schedule_packet_send(local_info_t *local, struct sta_info *sta)
 {
 	struct sk_buff *skb;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	struct hostap_80211_rx_status rx_stats;
 
 	if (skb_queue_empty(&sta->tx_buf))
@@ -2302,7 +2302,7 @@ static void schedule_packet_send(local_i
 		return;
 	}
 
-	hdr = (struct ieee80211_hdr *) skb_put(skb, 16);
+	hdr = (struct ieee80211_hdr_4addr *) skb_put(skb, 16);
 
 	/* Generate a fake pspoll frame to start packet delivery */
 	hdr->frame_ctl = __constant_cpu_to_le16(
@@ -2685,7 +2685,7 @@ ap_tx_ret hostap_handle_sta_tx(local_inf
 	struct sta_info *sta = NULL;
 	struct sk_buff *skb = tx->skb;
 	int set_tim, ret;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	struct hostap_skb_tx_data *meta;
 
 	meta = (struct hostap_skb_tx_data *) skb->cb;
@@ -2694,7 +2694,7 @@ ap_tx_ret hostap_handle_sta_tx(local_inf
 	    meta->iface->type == HOSTAP_INTERFACE_STA)
 		goto out;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
 	if (hdr->addr1[0] & 0x01) {
 		/* broadcast/multicast frame - no AP related processing */
@@ -2821,10 +2821,10 @@ void hostap_handle_sta_release(void *ptr
 void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb)
 {
 	struct sta_info *sta;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 	struct hostap_skb_tx_data *meta;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 	meta = (struct hostap_skb_tx_data *) skb->cb;
 
 	spin_lock(&local->ap->sta_table_lock);
@@ -2892,7 +2892,7 @@ static void hostap_update_sta_ps2(local_
 
 /* Called only as a tasklet (software IRQ). Called for each RX frame to update
  * STA power saving state. pwrmgt is a flag from 802.11 frame_ctl field. */
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr)
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr)
 {
 	struct sta_info *sta;
 	u16 fc;
@@ -2925,12 +2925,12 @@ ap_rx_ret hostap_handle_sta_rx(local_inf
 	int ret;
 	struct sta_info *sta;
 	u16 fc, type, stype;
-	struct ieee80211_hdr *hdr;
+	struct ieee80211_hdr_4addr *hdr;
 
 	if (local->ap == NULL)
 		return AP_RX_CONTINUE;
 
-	hdr = (struct ieee80211_hdr *) skb->data;
+	hdr = (struct ieee80211_hdr_4addr *) skb->data;
 
 	fc = le16_to_cpu(hdr->frame_ctl);
 	type = WLAN_FC_GET_TYPE(fc);
@@ -3058,7 +3058,7 @@ ap_rx_ret hostap_handle_sta_rx(local_inf
 
 /* Called only as a tasklet (software IRQ) */
 int hostap_handle_sta_crypto(local_info_t *local,
-			     struct ieee80211_hdr *hdr,
+			     struct ieee80211_hdr_4addr *hdr,
 			     struct ieee80211_crypt_data **crypt,
 			     void **sta_ptr)
 {
@@ -3160,7 +3160,7 @@ int hostap_add_sta(struct ap_data *ap, u
 
 /* Called only as a tasklet (software IRQ) */
 int hostap_update_rx_stats(struct ap_data *ap,
-			   struct ieee80211_hdr *hdr,
+			   struct ieee80211_hdr_4addr *hdr,
 			   struct hostap_80211_rx_status *rx_stats)
 {
 	struct sta_info *sta;
diff --git a/drivers/net/wireless/hostap/hostap_ap.h b/drivers/net/wireless/hostap/hostap_ap.h
index 816a52b..6d00df6 100644
--- a/drivers/net/wireless/hostap/hostap_ap.h
+++ b/drivers/net/wireless/hostap/hostap_ap.h
@@ -233,7 +233,7 @@ struct hostap_tx_data {
 ap_tx_ret hostap_handle_sta_tx(local_info_t *local, struct hostap_tx_data *tx);
 void hostap_handle_sta_release(void *ptr);
 void hostap_handle_sta_tx_exc(local_info_t *local, struct sk_buff *skb);
-int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr *hdr);
+int hostap_update_sta_ps(local_info_t *local, struct ieee80211_hdr_4addr *hdr);
 typedef enum {
 	AP_RX_CONTINUE, AP_RX_DROP, AP_RX_EXIT, AP_RX_CONTINUE_NOT_AUTHORIZED
 } ap_rx_ret;
@@ -241,13 +241,13 @@ ap_rx_ret hostap_handle_sta_rx(local_inf
 			       struct sk_buff *skb,
 			       struct hostap_80211_rx_status *rx_stats,
 			       int wds);
-int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr *hdr,
+int hostap_handle_sta_crypto(local_info_t *local, struct ieee80211_hdr_4addr *hdr,
 			     struct ieee80211_crypt_data **crypt,
 			     void **sta_ptr);
 int hostap_is_sta_assoc(struct ap_data *ap, u8 *sta_addr);
 int hostap_is_sta_authorized(struct ap_data *ap, u8 *sta_addr);
 int hostap_add_sta(struct ap_data *ap, u8 *sta_addr);
-int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr *hdr,
+int hostap_update_rx_stats(struct ap_data *ap, struct ieee80211_hdr_4addr *hdr,
 			   struct hostap_80211_rx_status *rx_stats);
 void hostap_update_rates(local_info_t *local);
 void hostap_add_wds_links(local_info_t *local);
---
0.99.8.GIT


--- NEW FILE 0187-ieee80211-Updated-hostap-to-be-compatible-with-extra_prefix_len-changes.txt ---
Subject: [PATCH] ieee80211: Updated hostap to be compatible with extra_prefix_len changes
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1127323431 -0500

tree 8c1676c8a15c08e6d4c718fc7cd42d9bf4cd8235
parent 0ccc3dd6469ed492578c184f47dde2baccde3593
author James Ketrenos <jketreno at linux.intel.com> 1126715240 -0500
committer James Ketrenos <jketreno at linux.intel.com> 1127316717 -0500

Updated hostap to be compatible with extra_prefix_len changes.

Accomplished via:

for i in hostap_ap.c hostap_80211_tx.c; do
        sed -i -e "s:\([.>]\)extra_prefix_len:\1extra_mpdu_prefix_len:g" \
                -e "s:\([.>]\)extra_postfix_len:\1extra_mpdu_postfix_len:g" \
                drivers/net/wireless/hostap/$i
done

CC: Jouni Malinen <jkmaline at cc.hut.fi>

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap_80211_tx.c |    8 ++++----
 drivers/net/wireless/hostap/hostap_ap.c       |    8 ++++----
 2 files changed, 8 insertions(+), 8 deletions(-)

applies-to: fe63cb09606c2c23485092bac7298c85677fea92
5bfc819b53ed67c76f33f969ab627070e85d87c1
diff --git a/drivers/net/wireless/hostap/hostap_80211_tx.c b/drivers/net/wireless/hostap/hostap_80211_tx.c
index 6db4543..9d24f8a 100644
--- a/drivers/net/wireless/hostap/hostap_80211_tx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_tx.c
@@ -317,10 +317,10 @@ struct sk_buff * hostap_tx_encrypt(struc
 	if (skb == NULL)
 		return NULL;
 
-	if ((skb_headroom(skb) < crypt->ops->extra_prefix_len ||
-	     skb_tailroom(skb) < crypt->ops->extra_postfix_len) &&
-	    pskb_expand_head(skb, crypt->ops->extra_prefix_len,
-			     crypt->ops->extra_postfix_len, GFP_ATOMIC)) {
+	if ((skb_headroom(skb) < crypt->ops->extra_mpdu_prefix_len ||
+	     skb_tailroom(skb) < crypt->ops->extra_mpdu_postfix_len) &&
+	    pskb_expand_head(skb, crypt->ops->extra_mpdu_prefix_len,
+			     crypt->ops->extra_mpdu_postfix_len, GFP_ATOMIC)) {
 		kfree_skb(skb);
 		return NULL;
 	}
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 070f703..087d926 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -1256,14 +1256,14 @@ static char * ap_auth_make_challenge(str
 	}
 
 	skb = dev_alloc_skb(WLAN_AUTH_CHALLENGE_LEN +
-			    ap->crypt->extra_prefix_len +
-			    ap->crypt->extra_postfix_len);
+			    ap->crypt->extra_mpdu_prefix_len +
+			    ap->crypt->extra_mpdu_postfix_len);
 	if (skb == NULL) {
 		kfree(tmpbuf);
 		return NULL;
 	}
 
-	skb_reserve(skb, ap->crypt->extra_prefix_len);
+	skb_reserve(skb, ap->crypt->extra_mpdu_prefix_len);
 	memset(skb_put(skb, WLAN_AUTH_CHALLENGE_LEN), 0,
 	       WLAN_AUTH_CHALLENGE_LEN);
 	if (ap->crypt->encrypt_mpdu(skb, 0, ap->crypt_priv)) {
@@ -1272,7 +1272,7 @@ static char * ap_auth_make_challenge(str
 		return NULL;
 	}
 
-	memcpy(tmpbuf, skb->data + ap->crypt->extra_prefix_len,
+	memcpy(tmpbuf, skb->data + ap->crypt->extra_mpdu_prefix_len,
 	       WLAN_AUTH_CHALLENGE_LEN);
 	dev_kfree_skb(skb);
 
---
0.99.8.GIT


--- NEW FILE 0189-forcedeth-add-hardware-tx-checksumming.txt ---
Subject: [PATCH] forcedeth: add hardware tx checksumming
From: Manfred Spraul <manfred at colorfullife.com>
Date: 1127359330 -0400

Recent forcedeth nics support checksum offloading for tx.

The attached patch, written by Ayaz Abdulla, adds the support to the
driver.

It also cleans up the handling of the three dma ring entry formats that
are supported by the driver.

Signed-off-By: Manfred Spraul <manfred at colorfullife.com>
Signed-off-By: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/forcedeth.c |   71 +++++++++++++++++++++++++++++------------------
 1 files changed, 44 insertions(+), 27 deletions(-)

applies-to: 6f1235f312251cccbb7f7d28f1e9c3f7fae0d0a2
8a4ae7f2e24bf99b61082ca45de8e54e70300b9d
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index 6e042ec..e5f4802 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -95,6 +95,7 @@
  *			   of nv_remove
  *      0.42: 06 Aug 2005: Fix lack of link speed initialization
  *			   in the second (and later) nv_open call
+ *      0.43: 10 Aug 2005: Add support for tx checksum.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -106,7 +107,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION		"0.41"
+#define FORCEDETH_VERSION		"0.43"
 #define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
@@ -145,6 +146,7 @@
 #define DEV_NEED_LINKTIMER	0x0002	/* poll link settings. Relies on the timer irq */
 #define DEV_HAS_LARGEDESC	0x0004	/* device supports jumbo frames and needs packet format 2 */
 #define DEV_HAS_HIGH_DMA        0x0008  /* device supports 64bit dma */
+#define DEV_HAS_CHECKSUM        0x0010  /* device supports tx and rx checksum offloads */
 
 enum {
 	NvRegIrqStatus = 0x000,
@@ -241,6 +243,9 @@ enum {
 #define NVREG_TXRXCTL_IDLE	0x0008
 #define NVREG_TXRXCTL_RESET	0x0010
 #define NVREG_TXRXCTL_RXCHECK	0x0400
+#define NVREG_TXRXCTL_DESC_1	0
+#define NVREG_TXRXCTL_DESC_2	0x02100
+#define NVREG_TXRXCTL_DESC_3	0x02200
 	NvRegMIIStatus = 0x180,
 #define NVREG_MIISTAT_ERROR		0x0001
 #define NVREG_MIISTAT_LINKCHANGE	0x0008
@@ -335,6 +340,8 @@ typedef union _ring_type {
 /* error and valid are the same for both */
 #define NV_TX2_ERROR		(1<<30)
 #define NV_TX2_VALID		(1<<31)
+#define NV_TX2_CHECKSUM_L3	(1<<27)
+#define NV_TX2_CHECKSUM_L4	(1<<26)
 
 #define NV_RX_DESCRIPTORVALID	(1<<16)
 #define NV_RX_MISSEDFRAME	(1<<17)
@@ -417,14 +424,14 @@ typedef union _ring_type {
 
 /* 
  * desc_ver values:
- * This field has two purposes:
- * - Newer nics uses a different ring layout. The layout is selected by
- *   comparing np->desc_ver with DESC_VER_xy.
- * - It contains bits that are forced on when writing to NvRegTxRxControl.
+ * The nic supports three different descriptor types:
+ * - DESC_VER_1: Original
+ * - DESC_VER_2: support for jumbo frames.
+ * - DESC_VER_3: 64-bit format.
  */
-#define DESC_VER_1	0x0
-#define DESC_VER_2	(0x02100|NVREG_TXRXCTL_RXCHECK)
-#define DESC_VER_3      (0x02200|NVREG_TXRXCTL_RXCHECK)
+#define DESC_VER_1	1
+#define DESC_VER_2	2
+#define DESC_VER_3	3
 
 /* PHY defines */
 #define PHY_OUI_MARVELL	0x5043
@@ -491,6 +498,7 @@ struct fe_priv {
 	u32 orig_mac[2];
 	u32 irqmask;
 	u32 desc_ver;
+	u32 txrxctl_bits;
 
 	void __iomem *base;
 
@@ -786,10 +794,10 @@ static void nv_txrx_reset(struct net_dev
 	u8 __iomem *base = get_hwbase(dev);
 
 	dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name);
-	writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->desc_ver, base + NvRegTxRxControl);
+	writel(NVREG_TXRXCTL_BIT2 | NVREG_TXRXCTL_RESET | np->txrxctl_bits, base + NvRegTxRxControl);
 	pci_push(base);
 	udelay(NV_TXRX_RESET_DELAY);
-	writel(NVREG_TXRXCTL_BIT2 | np->desc_ver, base + NvRegTxRxControl);
+	writel(NVREG_TXRXCTL_BIT2 | np->txrxctl_bits, base + NvRegTxRxControl);
 	pci_push(base);
 }
 
@@ -961,6 +969,7 @@ static int nv_start_xmit(struct sk_buff 
 {
 	struct fe_priv *np = get_nvpriv(dev);
 	int nr = np->next_tx % TX_RING;
+	u32 tx_checksum = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
 
 	np->tx_skbuff[nr] = skb;
 	np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len,
@@ -976,10 +985,10 @@ static int nv_start_xmit(struct sk_buff 
 	spin_lock_irq(&np->lock);
 	wmb();
 	if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
-		np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
+		np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags | tx_checksum);
 	else
-		np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags );
-	dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission.\n",
+		np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags | tx_checksum);
+	dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission\n",
 				dev->name, np->next_tx);
 	{
 		int j;
@@ -997,7 +1006,7 @@ static int nv_start_xmit(struct sk_buff 
 	if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP)
 		netif_stop_queue(dev);
 	spin_unlock_irq(&np->lock);
-	writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
+	writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
 	pci_push(get_hwbase(dev));
 	return 0;
 }
@@ -1408,7 +1417,7 @@ static int nv_change_mtu(struct net_devi
 		writel( ((RX_RING-1) << NVREG_RINGSZ_RXSHIFT) + ((TX_RING-1) << NVREG_RINGSZ_TXSHIFT),
 			base + NvRegRingSizes);
 		pci_push(base);
-		writel(NVREG_TXRXCTL_KICK|np->desc_ver, get_hwbase(dev) + NvRegTxRxControl);
+		writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
 		pci_push(base);
 
 		/* restart rx engine */
@@ -2115,9 +2124,9 @@ static int nv_open(struct net_device *de
 	/* 5) continue setup */
 	writel(np->linkspeed, base + NvRegLinkSpeed);
 	writel(NVREG_UNKSETUP3_VAL1, base + NvRegUnknownSetupReg3);
-	writel(np->desc_ver, base + NvRegTxRxControl);
+	writel(np->txrxctl_bits, base + NvRegTxRxControl);
 	pci_push(base);
-	writel(NVREG_TXRXCTL_BIT1|np->desc_ver, base + NvRegTxRxControl);
+	writel(NVREG_TXRXCTL_BIT1|np->txrxctl_bits, base + NvRegTxRxControl);
 	reg_delay(dev, NvRegUnknownSetupReg5, NVREG_UNKSETUP5_BIT31, NVREG_UNKSETUP5_BIT31,
 			NV_SETUP5_DELAY, NV_SETUP5_DELAYMAX,
 			KERN_INFO "open: SetupReg5, Bit 31 remained off\n");
@@ -2315,18 +2324,26 @@ static int __devinit nv_probe(struct pci
 			printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
 					pci_name(pci_dev));
 		}
+		np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
 	} else if (id->driver_data & DEV_HAS_LARGEDESC) {
 		/* packet format 2: supports jumbo frames */
 		np->desc_ver = DESC_VER_2;
+		np->txrxctl_bits = NVREG_TXRXCTL_DESC_2;
 	} else {
 		/* original packet format */
 		np->desc_ver = DESC_VER_1;
+		np->txrxctl_bits = NVREG_TXRXCTL_DESC_1;
 	}
 
 	np->pkt_limit = NV_PKTLIMIT_1;
 	if (id->driver_data & DEV_HAS_LARGEDESC)
 		np->pkt_limit = NV_PKTLIMIT_2;
 
+	if (id->driver_data & DEV_HAS_CHECKSUM) {
+		np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
+		dev->features |= NETIF_F_HW_CSUM;
+	}
+
 	err = -ENOMEM;
 	np->base = ioremap(addr, NV_PCI_REGSZ);
 	if (!np->base)
@@ -2527,35 +2544,35 @@ static struct pci_device_id pci_tbl[] = 
 	},
 	{	/* nForce3 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_4),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
 	},
 	{	/* nForce3 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_5),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
 	},
 	{	/* nForce3 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_6),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
 	},
 	{	/* nForce3 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_7),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM,
 	},
 	{	/* CK804 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_8),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
 	},
 	{	/* CK804 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_9),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
 	},
 	{	/* MCP04 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_10),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
 	},
 	{	/* MCP04 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_11),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
 	},
 	{	/* MCP51 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_12),
@@ -2567,11 +2584,11 @@ static struct pci_device_id pci_tbl[] = 
 	},
 	{	/* MCP55 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_14),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
 	},
 	{	/* MCP55 Ethernet Controller */
 		PCI_DEVICE(PCI_VENDOR_ID_NVIDIA, PCI_DEVICE_ID_NVIDIA_NVENET_15),
-		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_HIGH_DMA,
+		.driver_data = DEV_NEED_TIMERIRQ|DEV_NEED_LINKTIMER|DEV_HAS_LARGEDESC|DEV_HAS_CHECKSUM|DEV_HAS_HIGH_DMA,
 	},
 	{0,},
 };
---
0.99.8.GIT


--- NEW FILE 0198-ieee80211-update-orinoco-wl3501-drivers-for-latest-struct-naming.txt ---
Subject: [PATCH] ieee80211: update orinoco, wl3501 drivers for latest struct naming
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1127418187 -0400

---

 drivers/net/wireless/orinoco.c |    2 +-
 drivers/net/wireless/wl3501.h  |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

applies-to: 7cf648aba7823b1b7cc9419f682a2dca60cc2e82
af9288a707b609cdb1069cfe5bde0d6567c12c31
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 77e93a2..fc2fa4d 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -636,7 +636,7 @@ static void __orinoco_ev_txexc(struct ne
 	/* Read the frame header */
 	err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
 			       sizeof(struct hermes_tx_descriptor) +
-			       sizeof(struct ieee80211_hdr),
+			       sizeof(struct ieee80211_hdr_4addr),
 			       fid, 0);
 
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
diff --git a/drivers/net/wireless/wl3501.h b/drivers/net/wireless/wl3501.h
index 7fcbe58..4303c50 100644
--- a/drivers/net/wireless/wl3501.h
+++ b/drivers/net/wireless/wl3501.h
@@ -548,7 +548,7 @@ struct wl3501_80211_tx_plcp_hdr {
 
 struct wl3501_80211_tx_hdr {
 	struct wl3501_80211_tx_plcp_hdr	pclp_hdr;
-	struct ieee80211_hdr		mac_hdr;
+	struct ieee80211_hdr_4addr		mac_hdr;
 } __attribute__ ((packed));
 
 /*
---
0.99.8.GIT


--- NEW FILE 0211-orinoco-Remove-inneeded-system-includes.txt ---
Subject: [PATCH] orinoco: Remove inneeded system includes.
From: Pavel Roskin <proski at gnu.org>
Date: 1127463487 -0400

Signed-off-by: Pavel Roskin <proski at gnu.org>

Remove inneeded system includes.

Most system includes are not needed.  In particular, the hardware
backends don't need anything network related.  Some includes have been
moved from local headers to the C files where they are actually used.
Includes that have to be in the local headers are no longer from the C
sources.
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/airport.c        |   19 +------------------
 drivers/net/wireless/hermes.c         |   11 ++---------
 drivers/net/wireless/hermes.h         |    3 +--
 drivers/net/wireless/orinoco.c        |   12 ------------
 drivers/net/wireless/orinoco.h        |    2 --
 drivers/net/wireless/orinoco_cs.c     |   16 +---------------
 drivers/net/wireless/orinoco_nortel.c |   18 +-----------------
 drivers/net/wireless/orinoco_pci.c    |   18 +-----------------
 drivers/net/wireless/orinoco_plx.c    |   18 +-----------------
 drivers/net/wireless/orinoco_tmd.c    |   18 +-----------------
 drivers/net/wireless/spectrum_cs.c    |   16 +---------------
 11 files changed, 10 insertions(+), 141 deletions(-)

applies-to: 560986cb68a747de281f82ca605c7125ccc65c1c
ef846bf04f4c9e1a68ab841e89931f8c26100874
diff --git a/drivers/net/wireless/airport.c b/drivers/net/wireless/airport.c
index 9d49670..7b321f7 100644
--- a/drivers/net/wireless/airport.c
+++ b/drivers/net/wireless/airport.c
@@ -15,28 +15,11 @@
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
-#include <asm/io.h>
-#include <asm/system.h>
-#include <asm/current.h>
-#include <asm/prom.h>
-#include <asm/machdep.h>
+#include <linux/delay.h>
 #include <asm/pmac_feature.h>
-#include <asm/irq.h>
-#include <asm/uaccess.h>
 
 #include "orinoco.h"
 
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index 21c3d0d..eba0d9d 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -39,17 +39,10 @@
  */
 
 #include <linux/config.h>
-
 #include <linux/module.h>
-#include <linux/types.h>
-#include <linux/threads.h>
-#include <linux/smp.h>
-#include <asm/io.h>
-#include <linux/delay.h>
-#include <linux/init.h>
 #include <linux/kernel.h>
-#include <linux/net.h>
-#include <asm/errno.h>
+#include <linux/init.h>
+#include <linux/delay.h>
 
 #include "hermes.h"
 
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index 8c9e874..786613a 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -30,9 +30,8 @@
  * access to the hermes_t structure, and to the hardware
 */
 
-#include <linux/delay.h>
 #include <linux/if_ether.h>
-#include <asm/byteorder.h>
+#include <asm/io.h>
 
 /*
  * Limits and constants
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index fc2fa4d..f76fe3d 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -77,28 +77,16 @@
 #define DRIVER_NAME "orinoco"
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
 #include <linux/netdevice.h>
-#include <linux/if_arp.h>
 #include <linux/etherdevice.h>
 #include <linux/ethtool.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
 #include <net/ieee80211.h>
 
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
-#include "hermes.h"
 #include "hermes_rid.h"
 #include "orinoco.h"
 
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index c800563..32530d4 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -9,8 +9,6 @@
 
 #define DRIVER_VERSION "0.15rc2"
 
-#include <linux/types.h>
-#include <linux/spinlock.h>
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
 #include <net/iw_handler.h>
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 80920b1..195c530 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -14,30 +14,16 @@
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
-
+#include <linux/delay.h>
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
 #include "orinoco.h"
 
 /********************************************************************/
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
index 86fa58e..d48ec24 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -40,29 +40,13 @@
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/fcntl.h>
-
 #include <pcmcia/cisreg.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
 #define COR_OFFSET    (0xe0)	/* COR attribute offset of Prism2 PC card */
diff --git a/drivers/net/wireless/orinoco_pci.c b/drivers/net/wireless/orinoco_pci.c
index 42e0343..5362c21 100644
--- a/drivers/net/wireless/orinoco_pci.c
+++ b/drivers/net/wireless/orinoco_pci.c
@@ -93,28 +93,12 @@
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/fcntl.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
 /* All the magic there is from wlan-ng */
diff --git a/drivers/net/wireless/orinoco_plx.c b/drivers/net/wireless/orinoco_plx.c
index 7ab05b8..210e737 100644
--- a/drivers/net/wireless/orinoco_plx.c
+++ b/drivers/net/wireless/orinoco_plx.c
@@ -117,29 +117,13 @@
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/fcntl.h>
-
 #include <pcmcia/cisreg.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
 #define COR_OFFSET	(0x3e0)	/* COR attribute offset of Prism2 PC card */
diff --git a/drivers/net/wireless/orinoco_tmd.c b/drivers/net/wireless/orinoco_tmd.c
index 85893f4..5e68b70 100644
--- a/drivers/net/wireless/orinoco_tmd.c
+++ b/drivers/net/wireless/orinoco_tmd.c
@@ -53,29 +53,13 @@
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/timer.h>
-#include <linux/ioport.h>
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/list.h>
+#include <linux/delay.h>
 #include <linux/pci.h>
-#include <linux/fcntl.h>
-
 #include <pcmcia/cisreg.h>
 
-#include "hermes.h"
 #include "orinoco.h"
 
 #define COR_VALUE	(COR_LEVEL_REQ | COR_FUNC_ENA) /* Enable PC card with interrupt in level trigger */
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 63e0042..6119954 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -22,31 +22,17 @@
 #define PFX DRIVER_NAME ": "
 
 #include <linux/config.h>
-
 #include <linux/module.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
-#include <linux/sched.h>
-#include <linux/ptrace.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/ioport.h>
-#include <linux/netdevice.h>
-#include <linux/if_arp.h>
-#include <linux/etherdevice.h>
-#include <linux/wireless.h>
+#include <linux/delay.h>
 #include <linux/firmware.h>
-
 #include <pcmcia/cs_types.h>
 #include <pcmcia/cs.h>
 #include <pcmcia/cistpl.h>
 #include <pcmcia/cisreg.h>
 #include <pcmcia/ds.h>
 
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/system.h>
-
 #include "orinoco.h"
 
 static unsigned char *primsym;
---
0.99.8.GIT


--- NEW FILE 0212-orinoco-Make-nortel_pci_hw_init-static.txt ---
Subject: [PATCH] orinoco: Make nortel_pci_hw_init() static.
From: Pavel Roskin <proski at gnu.org>
Date: 1127463486 -0400

Signed-off-by: Pavel Roskin <proski at gnu.org>

Make nortel_pci_hw_init() static.

Found by sparse.
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco_nortel.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 20a1f3808166d65f98db97944870e20143c05067
4c08202547111e503eca4031ae9443159a79e2b2
diff --git a/drivers/net/wireless/orinoco_nortel.c b/drivers/net/wireless/orinoco_nortel.c
index d48ec24..d8afd51 100644
--- a/drivers/net/wireless/orinoco_nortel.c
+++ b/drivers/net/wireless/orinoco_nortel.c
@@ -92,7 +92,7 @@ static int nortel_pci_cor_reset(struct o
 	return 0;
 }
 
-int nortel_pci_hw_init(struct nortel_pci_card *card)
+static int nortel_pci_hw_init(struct nortel_pci_card *card)
 {
 	int i;
 	u32 reg;
---
0.99.8.GIT


--- NEW FILE 0213-orinoco-Fix-memory-leak-and-unneeded-unlock-in-orinoco_join_ap.txt ---
Subject: [PATCH] orinoco: Fix memory leak and unneeded unlock in orinoco_join_ap()
From: Pavel Roskin <proski at gnu.org>
Date: 1127463486 -0400

Signed-off-by: Pavel Roskin <proski at gnu.org>

Fix memory leak and unneeded unlock in orinoco_join_ap()

If orinoco_lock() fails, the code would still run orinoco_unlock(),
instead of freeing the allocated memory.  Found by sparse.
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

applies-to: 16e191f069d0d722a61cbab76ab77fa587162386
f3cb4cc120177090b0ccc9fb20a12010de39ac8a
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index f76fe3d..8b93b44 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -1046,7 +1046,7 @@ static void orinoco_join_ap(struct net_d
 		return;
 
 	if (orinoco_lock(priv, &flags) != 0)
-		goto out;
+		goto fail_lock;
 
 	/* Sanity checks in case user changed something in the meantime */
 	if (! priv->bssid_fixed)
@@ -1091,8 +1091,10 @@ static void orinoco_join_ap(struct net_d
 		printk(KERN_ERR "%s: Error issuing join request\n", dev->name);
 
  out:
-	kfree(buf);
 	orinoco_unlock(priv, &flags);
+
+ fail_lock:
+	kfree(buf);
 }
 
 /* Send new BSSID to userspace */
---
0.99.8.GIT


--- NEW FILE 0214-orinoco-orinoco_send_wevents-could-return-without-unlocking.txt ---
Subject: [PATCH] orinoco: orinoco_send_wevents() could return without unlocking.
From: Pavel Roskin <proski at gnu.org>
Date: 1127463486 -0400

Signed-off-by: Pavel Roskin <proski at gnu.org>

orinoco_send_wevents() could return without unlocking.

Failure to read BSSID from the hardware would cause orinoco_send_wevents() to
return with lock held.  Found by sparse.
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

applies-to: 368c76f705f9512f5016288b607e3a0e4b36d54d
8aeabc375041a5fe9c9be315472497b2e0547eed
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 8b93b44..29cb5d8 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -1112,12 +1112,14 @@ static void orinoco_send_wevents(struct 
 	err = hermes_read_ltv(hw, IRQ_BAP, HERMES_RID_CURRENTBSSID,
 			      ETH_ALEN, NULL, wrqu.ap_addr.sa_data);
 	if (err != 0)
-		return;
+		goto out;
 
 	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
 
 	/* Send event to user space */
 	wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
+
+ out:
 	orinoco_unlock(priv, &flags);
 }
 
---
0.99.8.GIT


--- NEW FILE 0215-orinoco-Remove-unneeded-forward-declarations.txt ---
Subject: [PATCH] orinoco: Remove unneeded forward declarations.
From: Pavel Roskin <proski at gnu.org>
Date: 1127463486 -0400

Signed-off-by: Pavel Roskin <proski at gnu.org>

Remove unneeded forward declarations.

Also reorder struct pcmcia_driver initialization to keep attach and
detach together.
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco_cs.c  |   15 +++------------
 drivers/net/wireless/spectrum_cs.c |   15 +++------------
 2 files changed, 6 insertions(+), 24 deletions(-)

applies-to: 27f79b27bc015596395c03ecd9c6ae72964fb322
393da59834eef526fc6fd0df321e94344d7c49e3
diff --git a/drivers/net/wireless/orinoco_cs.c b/drivers/net/wireless/orinoco_cs.c
index 195c530..dc1128a 100644
--- a/drivers/net/wireless/orinoco_cs.c
+++ b/drivers/net/wireless/orinoco_cs.c
@@ -80,17 +80,8 @@ static dev_link_t *dev_list; /* = NULL *
 /* Function prototypes						    */
 /********************************************************************/
 
-/* device methods */
-static int orinoco_cs_hard_reset(struct orinoco_private *priv);
-
-/* PCMCIA gumpf */
-static void orinoco_cs_config(dev_link_t * link);
-static void orinoco_cs_release(dev_link_t * link);
-static int orinoco_cs_event(event_t event, int priority,
-			    event_callback_args_t * args);
-
-static dev_link_t *orinoco_cs_attach(void);
-static void orinoco_cs_detach(dev_link_t *);
+static void orinoco_cs_release(dev_link_t *link);
+static void orinoco_cs_detach(dev_link_t *link);
 
 /********************************************************************/
 /* Device methods     						    */
@@ -675,8 +666,8 @@ static struct pcmcia_driver orinoco_driv
 		.name	= DRIVER_NAME,
 	},
 	.attach		= orinoco_cs_attach,
-	.event		= orinoco_cs_event,
 	.detach		= orinoco_cs_detach,
+	.event		= orinoco_cs_event,
 	.id_table       = orinoco_cs_ids,
 };
 
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index 6119954..ceed024 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -89,17 +89,8 @@ static dev_link_t *dev_list; /* = NULL *
 /* Function prototypes						    */
 /********************************************************************/
 
-/* device methods */
-static int spectrum_cs_hard_reset(struct orinoco_private *priv);
-
-/* PCMCIA gumpf */
-static void spectrum_cs_config(dev_link_t * link);
-static void spectrum_cs_release(dev_link_t * link);
-static int spectrum_cs_event(event_t event, int priority,
-			    event_callback_args_t * args);
-
-static dev_link_t *spectrum_cs_attach(void);
-static void spectrum_cs_detach(dev_link_t *);
+static void spectrum_cs_release(dev_link_t *link);
+static void spectrum_cs_detach(dev_link_t *link);
 
 /********************************************************************/
 /* Firmware downloader						    */
@@ -1058,8 +1049,8 @@ static struct pcmcia_driver orinoco_driv
 		.name	= DRIVER_NAME,
 	},
 	.attach		= spectrum_cs_attach,
-	.event		= spectrum_cs_event,
 	.detach		= spectrum_cs_detach,
+	.event		= spectrum_cs_event,
 	.id_table       = spectrum_cs_ids,
 };
 
---
0.99.8.GIT


--- NEW FILE 0216-orinoco-Annotate-endianess-of-variables-and-structure-members.txt ---
Subject: [PATCH] orinoco: Annotate endianess of variables and structure members.
From: Pavel Roskin <proski at gnu.org>
Date: 1127463486 -0400

Signed-off-by: Pavel Roskin <proski at gnu.org>

Annotate endianess of variables and structure members.

Don't reuse variables for both host-endian and little-endian data.
Minor comment changes in affected structures.
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hermes.h      |  108 ++++++++++++++++++------------------
 drivers/net/wireless/orinoco.c     |   62 +++++++++++----------
 drivers/net/wireless/orinoco.h     |    6 +-
 drivers/net/wireless/spectrum_cs.c |   20 +++----
 4 files changed, 99 insertions(+), 97 deletions(-)

applies-to: bf4285c3f2064b56c2b188d4f24fe2b3d740290b
d133ae4cd6a3c75c31b1630f906cc9979a11077f
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index 786613a..ad28e32 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -191,13 +191,13 @@
 #define	HERMES_RXSTAT_WMP		(0x6000)	/* Wavelan-II Management Protocol frame */
 
 struct hermes_tx_descriptor {
-	u16 status;
-	u16 reserved1;
-	u16 reserved2;
-	u32 sw_support;
+	__le16 status;
+	__le16 reserved1;
+	__le16 reserved2;
+	__le32 sw_support;
 	u8 retry_count;
 	u8 tx_rate;
-	u16 tx_control;	
+	__le16 tx_control;	
 } __attribute__ ((packed));
 
 #define HERMES_TXSTAT_RETRYERR		(0x0001)
@@ -221,60 +221,60 @@ struct hermes_tx_descriptor {
 #define HERMES_INQ_SEC_STAT_AGERE	(0xF202)
 
 struct hermes_tallies_frame {
-	u16 TxUnicastFrames;
-	u16 TxMulticastFrames;
-	u16 TxFragments;
-	u16 TxUnicastOctets;
-	u16 TxMulticastOctets;
-	u16 TxDeferredTransmissions;
-	u16 TxSingleRetryFrames;
-	u16 TxMultipleRetryFrames;
-	u16 TxRetryLimitExceeded;
-	u16 TxDiscards;
-	u16 RxUnicastFrames;
-	u16 RxMulticastFrames;
-	u16 RxFragments;
-	u16 RxUnicastOctets;
-	u16 RxMulticastOctets;
-	u16 RxFCSErrors;
-	u16 RxDiscards_NoBuffer;
-	u16 TxDiscardsWrongSA;
-	u16 RxWEPUndecryptable;
-	u16 RxMsgInMsgFragments;
-	u16 RxMsgInBadMsgFragments;
+	__le16 TxUnicastFrames;
+	__le16 TxMulticastFrames;
+	__le16 TxFragments;
+	__le16 TxUnicastOctets;
+	__le16 TxMulticastOctets;
+	__le16 TxDeferredTransmissions;
+	__le16 TxSingleRetryFrames;
+	__le16 TxMultipleRetryFrames;
+	__le16 TxRetryLimitExceeded;
+	__le16 TxDiscards;
+	__le16 RxUnicastFrames;
+	__le16 RxMulticastFrames;
+	__le16 RxFragments;
+	__le16 RxUnicastOctets;
+	__le16 RxMulticastOctets;
+	__le16 RxFCSErrors;
+	__le16 RxDiscards_NoBuffer;
+	__le16 TxDiscardsWrongSA;
+	__le16 RxWEPUndecryptable;
+	__le16 RxMsgInMsgFragments;
+	__le16 RxMsgInBadMsgFragments;
 	/* Those last are probably not available in very old firmwares */
-	u16 RxDiscards_WEPICVError;
-	u16 RxDiscards_WEPExcluded;
+	__le16 RxDiscards_WEPICVError;
+	__le16 RxDiscards_WEPExcluded;
 } __attribute__ ((packed));
 
 /* Grabbed from wlan-ng - Thanks Mark... - Jean II
  * This is the result of a scan inquiry command */
 /* Structure describing info about an Access Point */
 struct prism2_scan_apinfo {
-	u16 channel;		/* Channel where the AP sits */
-	u16 noise;		/* Noise level */
-	u16 level;		/* Signal level */
+	__le16 channel;		/* Channel where the AP sits */
+	__le16 noise;		/* Noise level */
+	__le16 level;		/* Signal level */
 	u8 bssid[ETH_ALEN];	/* MAC address of the Access Point */
-	u16 beacon_interv;	/* Beacon interval */
-	u16 capabilities;	/* Capabilities */
-	u16 essid_len;		/* ESSID length */
+	__le16 beacon_interv;	/* Beacon interval */
+	__le16 capabilities;	/* Capabilities */
+	__le16 essid_len;	/* ESSID length */
 	u8 essid[32];		/* ESSID of the network */
 	u8 rates[10];		/* Bit rate supported */
-	u16 proberesp_rate;	/* Data rate of the response frame */
-	u16 atim;		/* ATIM window time, Kus (hostscan only) */
+	__le16 proberesp_rate;	/* Data rate of the response frame */
+	__le16 atim;		/* ATIM window time, Kus (hostscan only) */
 } __attribute__ ((packed));
 
 /* Same stuff for the Lucent/Agere card.
  * Thanks to h1kari <h1kari AT dachb0den.com> - Jean II */
 struct agere_scan_apinfo {
-	u16 channel;		/* Channel where the AP sits */
-	u16 noise;		/* Noise level */
-	u16 level;		/* Signal level */
+	__le16 channel;		/* Channel where the AP sits */
+	__le16 noise;		/* Noise level */
+	__le16 level;		/* Signal level */
 	u8 bssid[ETH_ALEN];	/* MAC address of the Access Point */
-	u16 beacon_interv;	/* Beacon interval */
-	u16 capabilities;	/* Capabilities */
+	__le16 beacon_interv;	/* Beacon interval */
+	__le16 capabilities;	/* Capabilities */
 	/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
-	u16 essid_len;		/* ESSID length */
+	__le16 essid_len;	/* ESSID length */
 	u8 essid[32];		/* ESSID of the network */
 } __attribute__ ((packed));
 
@@ -282,16 +282,16 @@ struct agere_scan_apinfo {
 struct symbol_scan_apinfo {
 	u8 channel;		/* Channel where the AP sits */
 	u8 unknown1;		/* 8 in 2.9x and 3.9x f/w, 0 otherwise */
-	u16 noise;		/* Noise level */
-	u16 level;		/* Signal level */
+	__le16 noise;		/* Noise level */
+	__le16 level;		/* Signal level */
 	u8 bssid[ETH_ALEN];	/* MAC address of the Access Point */
-	u16 beacon_interv;	/* Beacon interval */
-	u16 capabilities;	/* Capabilities */
+	__le16 beacon_interv;	/* Beacon interval */
+	__le16 capabilities;	/* Capabilities */
 	/* bits: 0-ess, 1-ibss, 4-privacy [wep] */
-	u16 essid_len;		/* ESSID length */
+	__le16 essid_len;	/* ESSID length */
 	u8 essid[32];		/* ESSID of the network */
-    	u16 rates[5];		/* Bit rate supported */
-	u16 basic_rates;	/* Basic rates bitmask */
+    	__le16 rates[5];	/* Bit rate supported */
+	__le16 basic_rates;	/* Basic rates bitmask */
 	u8 unknown2[6];		/* Always FF:FF:FF:FF:00:00 */
 	u8 unknown3[8];		/* Always 0, appeared in f/w 3.91-68 */
 } __attribute__ ((packed));
@@ -311,7 +311,7 @@ union hermes_scan_info {
 #define HERMES_LINKSTATUS_ASSOC_FAILED    (0x0006)
   
 struct hermes_linkstatus {
-	u16 linkstatus;         /* Link status */
+	__le16 linkstatus;         /* Link status */
 } __attribute__ ((packed));
 
 struct hermes_response {
@@ -320,8 +320,8 @@ struct hermes_response {
 
 /* "ID" structure - used for ESSID and station nickname */
 struct hermes_idstring {
-	u16 len;
-	u16 val[16];
+	__le16 len;
+	__le16 val[16];
 } __attribute__ ((packed));
 
 struct hermes_multicast {
@@ -446,7 +446,7 @@ static inline void hermes_clear_words(st
 
 static inline int hermes_read_wordrec(hermes_t *hw, int bap, u16 rid, u16 *word)
 {
-	u16 rec;
+	__le16 rec;
 	int err;
 
 	err = HERMES_READ_RECORD(hw, bap, rid, &rec);
@@ -456,7 +456,7 @@ static inline int hermes_read_wordrec(he
 
 static inline int hermes_write_wordrec(hermes_t *hw, int bap, u16 rid, u16 word)
 {
-	u16 rec = cpu_to_le16(word);
+	__le16 rec = cpu_to_le16(word);
 	return HERMES_WRITE_RECORD(hw, bap, rid, &rec);
 }
 
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 29cb5d8..1ae301c 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -202,31 +202,32 @@ static struct {
 /********************************************************************/
 
 /* Used in Event handling.
- * We avoid nested structres as they break on ARM -- Moustafa */
+ * We avoid nested structures as they break on ARM -- Moustafa */
 struct hermes_tx_descriptor_802_11 {
 	/* hermes_tx_descriptor */
-	u16 status;
-	u16 reserved1;
-	u16 reserved2;
-	u32 sw_support;
+	__le16 status;
+	__le16 reserved1;
+	__le16 reserved2;
+	__le32 sw_support;
 	u8 retry_count;
 	u8 tx_rate;
-	u16 tx_control;
+	__le16 tx_control;
 
-	/* ieee802_11_hdr */
-	u16 frame_ctl;
-	u16 duration_id;
+	/* ieee80211_hdr */
+	__le16 frame_ctl;
+	__le16 duration_id;
 	u8 addr1[ETH_ALEN];
 	u8 addr2[ETH_ALEN];
 	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
+	__le16 seq_ctl;
 	u8 addr4[ETH_ALEN];
-	u16 data_len;
+
+	__le16 data_len;
 
 	/* ethhdr */
-	unsigned char   h_dest[ETH_ALEN];       /* destination eth addr */
-	unsigned char   h_source[ETH_ALEN];     /* source ether addr    */
-	unsigned short  h_proto;                /* packet type ID field */
+	u8 h_dest[ETH_ALEN];	/* destination eth addr */
+	u8 h_source[ETH_ALEN];	/* source ether addr    */
+	__be16 h_proto;		/* packet type ID field */
 
 	/* p8022_hdr */
 	u8 dsap;
@@ -234,31 +235,31 @@ struct hermes_tx_descriptor_802_11 {
 	u8 ctrl;
 	u8 oui[3];
 
-	u16 ethertype;
+	__be16 ethertype;
 } __attribute__ ((packed));
 
 /* Rx frame header except compatibility 802.3 header */
 struct hermes_rx_descriptor {
 	/* Control */
-	u16 status;
-	u32 time;
+	__le16 status;
+	__le32 time;
 	u8 silence;
 	u8 signal;
 	u8 rate;
 	u8 rxflow;
-	u32 reserved;
+	__le32 reserved;
 
 	/* 802.11 header */
-	u16 frame_ctl;
-	u16 duration_id;
+	__le16 frame_ctl;
+	__le16 duration_id;
 	u8 addr1[ETH_ALEN];
 	u8 addr2[ETH_ALEN];
 	u8 addr3[ETH_ALEN];
-	u16 seq_ctl;
+	__le16 seq_ctl;
 	u8 addr4[ETH_ALEN];
 
 	/* Data length */
-	u16 data_len;
+	__le16 data_len;
 } __attribute__ ((packed));
 
 /********************************************************************/
@@ -389,7 +390,7 @@ static struct iw_statistics *orinoco_get
 		}
 	} else {
 		struct {
-			u16 qual, signal, noise;
+			__le16 qual, signal, noise;
 		} __attribute__ ((packed)) cq;
 
 		err = HERMES_READ_RECORD(hw, USER_BAP,
@@ -615,6 +616,7 @@ static void __orinoco_ev_txexc(struct ne
 	struct orinoco_private *priv = netdev_priv(dev);
 	struct net_device_stats *stats = &priv->stats;
 	u16 fid = hermes_read_regn(hw, TXCOMPLFID);
+	u16 status;
 	struct hermes_tx_descriptor_802_11 hdr;
 	int err = 0;
 
@@ -644,8 +646,8 @@ static void __orinoco_ev_txexc(struct ne
 	 * exceeded, because that's the only status that really mean
 	 * that this particular node went away.
 	 * Other errors means that *we* screwed up. - Jean II */
-	hdr.status = le16_to_cpu(hdr.status);
-	if (hdr.status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
+	status = le16_to_cpu(hdr.status);
+	if (status & (HERMES_TXSTAT_RETRYERR | HERMES_TXSTAT_AGEDERR)) {
 		union iwreq_data	wrqu;
 
 		/* Copy 802.11 dest address.
@@ -1031,7 +1033,7 @@ static void orinoco_join_ap(struct net_d
 	unsigned long flags;
 	struct join_req {
 		u8 bssid[ETH_ALEN];
-		u16 channel;
+		__le16 channel;
 	} __attribute__ ((packed)) req;
 	const int atom_len = offsetof(struct prism2_scan_apinfo, atim);
 	struct prism2_scan_apinfo *atom = NULL;
@@ -1128,8 +1130,8 @@ static void __orinoco_ev_info(struct net
 	struct orinoco_private *priv = netdev_priv(dev);
 	u16 infofid;
 	struct {
-		u16 len;
-		u16 type;
+		__le16 len;
+		__le16 type;
 	} __attribute__ ((packed)) info;
 	int len, type;
 	int err;
@@ -3905,7 +3907,7 @@ static int orinoco_ioctl_setscan(struct 
 						   HERMES_HOSTSCAN_SYMBOL_BCAST);
 			break;
 		case FIRMWARE_TYPE_INTERSIL: {
-			u16 req[3];
+			__le16 req[3];
 
 			req[0] = cpu_to_le16(0x3fff);	/* All channels */
 			req[1] = cpu_to_le16(0x0001);	/* rate 1 Mbps */
@@ -3979,7 +3981,7 @@ static inline int orinoco_translate_scan
 	case FIRMWARE_TYPE_INTERSIL:
 		offset = 4;
 		if (priv->has_hostscan) {
-			atom_len = le16_to_cpup((u16 *)scan);
+			atom_len = le16_to_cpup((__le16 *)scan);
 			/* Sanity check for atom_len */
 			if (atom_len < sizeof(struct prism2_scan_apinfo)) {
 				printk(KERN_ERR "%s: Invalid atom_len in scan data: %d\n",
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 32530d4..6920ead 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -27,7 +27,7 @@
 #define ORINOCO_MAX_KEYS	4
 
 struct orinoco_key {
-	u16 len;	/* always stored as little-endian */
+	__le16 len;	/* always stored as little-endian */
 	char data[ORINOCO_MAX_KEY_SIZE];
 } __attribute__ ((packed));
 
@@ -35,14 +35,14 @@ struct header_struct {
 	/* 802.3 */
 	u8 dest[ETH_ALEN];
 	u8 src[ETH_ALEN];
-	u16 len;
+	__be16 len;
 	/* 802.2 */
 	u8 dsap;
 	u8 ssap;
 	u8 ctrl;
 	/* SNAP */
 	u8 oui[3];
-	u16 ethertype;
+	unsigned short ethertype;
 } __attribute__ ((packed));
 
 typedef enum {
diff --git a/drivers/net/wireless/spectrum_cs.c b/drivers/net/wireless/spectrum_cs.c
index ceed024..b1bbc8e 100644
--- a/drivers/net/wireless/spectrum_cs.c
+++ b/drivers/net/wireless/spectrum_cs.c
@@ -138,8 +138,8 @@ static void spectrum_cs_detach(dev_link_
  * Each block has the following structure.
  */
 struct dblock {
-	u32 _addr;		/* adapter address where to write the block */
-	u16 _len;		/* length of the data only, in bytes */
+	__le32 _addr;		/* adapter address where to write the block */
+	__le16 _len;		/* length of the data only, in bytes */
 	char data[0];		/* data to be written */
 } __attribute__ ((packed));
 
@@ -149,9 +149,9 @@ struct dblock {
  * items with matching ID should be written.
  */
 struct pdr {
-	u32 _id;		/* record ID */
-	u32 _addr;		/* adapter address where to write the data */
-	u32 _len;		/* expected length of the data, in bytes */
+	__le32 _id;		/* record ID */
+	__le32 _addr;		/* adapter address where to write the data */
+	__le32 _len;		/* expected length of the data, in bytes */
 	char next[0];		/* next PDR starts here */
 } __attribute__ ((packed));
 
@@ -162,8 +162,8 @@ struct pdr {
  * be plugged into the secondary firmware.
  */
 struct pdi {
-	u16 _len;		/* length of ID and data, in words */
-	u16 _id;		/* record ID */
+	__le16 _len;		/* length of ID and data, in words */
+	__le16 _id;		/* record ID */
 	char data[0];		/* plug data */
 } __attribute__ ((packed));;
 
@@ -370,7 +370,7 @@ spectrum_plug_pdi(hermes_t *hw, struct p
 
 /* Read PDA from the adapter */
 static int
-spectrum_read_pda(hermes_t *hw, u16 *pda, int pda_len)
+spectrum_read_pda(hermes_t *hw, __le16 *pda, int pda_len)
 {
 	int ret;
 	int pda_size;
@@ -401,7 +401,7 @@ spectrum_read_pda(hermes_t *hw, u16 *pda
 /* Parse PDA and write the records into the adapter */
 static int
 spectrum_apply_pda(hermes_t *hw, const struct dblock *first_block,
-		   u16 *pda)
+		   __le16 *pda)
 {
 	int ret;
 	struct pdi *pdi;
@@ -467,7 +467,7 @@ spectrum_dl_image(hermes_t *hw, dev_link
 	const struct dblock *first_block;
 
 	/* Plug Data Area (PDA) */
-	u16 pda[PDA_WORDS];
+	__le16 pda[PDA_WORDS];
 
 	/* Binary block begins after the 0x1A marker */
 	ptr = image;
---
0.99.8.GIT


--- NEW FILE 0217-orinoco-Read-only-needed-data-in-__orinoco_ev_txexc.txt ---
Subject: [PATCH] orinoco: Read only needed data in __orinoco_ev_txexc().
From: Pavel Roskin <proski at gnu.org>
Date: 1127463486 -0400

Signed-off-by: Pavel Roskin <proski at gnu.org>

Read only needed data in __orinoco_ev_txexc().

Don't read the 802.11 header beyond addr1.  The rest of the frame is not
used currently.
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

applies-to: 4b292054c342e6e8c5b2594c62cbf3534eea1edf
48ca703807eba616ad5e384b40e27514bd341a3d
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 1ae301c..78afbc7 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -623,10 +623,10 @@ static void __orinoco_ev_txexc(struct ne
 	if (fid == DUMMY_FID)
 		return; /* Nothing's really happened */
 
-	/* Read the frame header */
+	/* Read part of the frame header - we need status and addr1 */
 	err = hermes_bap_pread(hw, IRQ_BAP, &hdr,
-			       sizeof(struct hermes_tx_descriptor) +
-			       sizeof(struct ieee80211_hdr_4addr),
+			       offsetof(struct hermes_tx_descriptor_802_11,
+					addr2),
 			       fid, 0);
 
 	hermes_write_regn(hw, TXCOMPLFID, DUMMY_FID);
---
0.99.8.GIT


--- NEW FILE 0218-orinoco-Bump-version-to-0.15rc3.txt ---
Subject: [PATCH] orinoco: Bump version to 0.15rc3.
From: Pavel Roskin <proski at gnu.org>
Date: 1127463486 -0400

Signed-off-by: Pavel Roskin <proski at gnu.org>

Bump version to 0.15rc3.
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: ca4a41c2a653ff89ff1e713109e9afe4978a12e6
acc4b985a6f8f22a0e826692894a4af234764001
diff --git a/drivers/net/wireless/orinoco.h b/drivers/net/wireless/orinoco.h
index 6920ead..7a17bb3 100644
--- a/drivers/net/wireless/orinoco.h
+++ b/drivers/net/wireless/orinoco.h
@@ -7,7 +7,7 @@
 #ifndef _ORINOCO_H
 #define _ORINOCO_H
 
-#define DRIVER_VERSION "0.15rc2"
+#define DRIVER_VERSION "0.15rc3"
 
 #include <linux/netdevice.h>
 #include <linux/wireless.h>
---
0.99.8.GIT


--- NEW FILE 0263-hostap-Fix-pci_driver-name-for-hostap_plx-and-hostap_pci.txt ---
Subject: [PATCH] hostap: Fix pci_driver name for hostap_plx and hostap_pci
From: Pavel Roskin <proski at gnu.org>
Date: 1127537938 -0700

hostap_pci and hostap_plx drivers still use PCI driver names
"prism2_pci" and "prism2_plx" respectively.  This is unfriendly to
linux-wlan-ng, which uses the same names.  So, if e.g. hostap_pci and
prism2_pci are loaded, they will "share" /sys/bus/pci/drivers/prism2_plx
directory.

Change PCI driver names of hostap_pci and hostap_plx to be equal to
their module names.

Signed-off-by: Pavel Roskin <proski at gnu.org>
Signed-off-by: Jouni Malinen <jkmaline at cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap_pci.c |    2 +-
 drivers/net/wireless/hostap/hostap_plx.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

applies-to: 067920155bf3cf6896e88d1cff8c170d32768922
7a716536c602be6050b4f3ece30f1fc3b64362b0
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 025f8cd..b9254f7 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -441,7 +441,7 @@ static int prism2_pci_resume(struct pci_
 MODULE_DEVICE_TABLE(pci, prism2_pci_id_table);
 
 static struct pci_driver prism2_pci_drv_id = {
-	.name		= "prism2_pci",
+	.name		= "hostap_pci",
 	.id_table	= prism2_pci_id_table,
 	.probe		= prism2_pci_probe,
 	.remove		= prism2_pci_remove,
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 474ef83..1abebdf 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -616,7 +616,7 @@ static void prism2_plx_remove(struct pci
 MODULE_DEVICE_TABLE(pci, prism2_plx_id_table);
 
 static struct pci_driver prism2_plx_drv_id = {
-	.name		= "prism2_plx",
+	.name		= "hostap_plx",
 	.id_table	= prism2_plx_id_table,
 	.probe		= prism2_plx_probe,
 	.remove		= prism2_plx_remove,
---
0.99.8.GIT


--- NEW FILE 0264-hostap-Add-support-for-WE-19.txt ---
Subject: [PATCH] hostap: Add support for WE-19
From: Jean Tourrilhes <jt at hpl.hp.com>
Date: 1127537939 -0700

This patch adds support for WE-19 to the HostAP driver. One of
the major change is the use of an explicit flag to tell if iwstat is
in dBm or not.

Signed-off-by: Jouni Malinen <jkmaline at cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap_80211_rx.c |    3 ++-
 drivers/net/wireless/hostap/hostap_ap.c       |    6 +++---
 drivers/net/wireless/hostap/hostap_ioctl.c    |    9 +++++++--
 3 files changed, 12 insertions(+), 6 deletions(-)

applies-to: 58ed691a144e75b81b712ccdf5daccebbe58693a
c28df16ed70d1b6cefd12135e3c68bfccd1bb635
diff --git a/drivers/net/wireless/hostap/hostap_80211_rx.c b/drivers/net/wireless/hostap/hostap_80211_rx.c
index 42e61c6..ffac508 100644
--- a/drivers/net/wireless/hostap/hostap_80211_rx.c
+++ b/drivers/net/wireless/hostap/hostap_80211_rx.c
@@ -737,7 +737,8 @@ void hostap_80211_rx(struct net_device *
 		struct iw_quality wstats;
 		wstats.level = rx_stats->signal;
 		wstats.noise = rx_stats->noise;
-		wstats.updated = 6;	/* No qual value */
+		wstats.updated = IW_QUAL_LEVEL_UPDATED | IW_QUAL_NOISE_UPDATED
+			| IW_QUAL_QUAL_INVALID | IW_QUAL_DBM;
 		/* Update spy records */
 		wireless_spy_update(dev, hdr->addr2, &wstats);
 	}
diff --git a/drivers/net/wireless/hostap/hostap_ap.c b/drivers/net/wireless/hostap/hostap_ap.c
index 087d926..9da94ab 100644
--- a/drivers/net/wireless/hostap/hostap_ap.c
+++ b/drivers/net/wireless/hostap/hostap_ap.c
@@ -2349,7 +2349,7 @@ static int prism2_ap_get_sta_qual(local_
 		qual[count].noise = HFA384X_LEVEL_TO_dBm(sta->last_rx_silence);
 		qual[count].updated = sta->last_rx_updated;
 
-		sta->last_rx_updated = 0;
+		sta->last_rx_updated = IW_QUAL_DBM;
 
 		count++;
 		if (count >= buf_size)
@@ -2467,7 +2467,7 @@ static int prism2_ap_translate_scan(stru
 		}
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
-		sta->last_rx_updated = 0;
+		sta->last_rx_updated = IW_QUAL_DBM;
 
 		/* To be continued, we should make good use of IWEVCUSTOM */
 	}
@@ -3174,7 +3174,7 @@ int hostap_update_rx_stats(struct ap_dat
 		sta->last_rx_silence = rx_stats->noise;
 		sta->last_rx_signal = rx_stats->signal;
 		sta->last_rx_rate = rx_stats->rate;
-		sta->last_rx_updated = 7;
+		sta->last_rx_updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
 		if (rx_stats->rate == 10)
 			sta->rx_count[0]++;
 		else if (rx_stats->rate == 20)
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index e720369..dd98172 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -50,7 +50,8 @@ static struct iw_statistics *hostap_get_
 #endif /* in_atomic */
 
 		if (update && prism2_update_comms_qual(dev) == 0)
-			wstats->qual.updated = 7;
+			wstats->qual.updated = IW_QUAL_ALL_UPDATED |
+				IW_QUAL_DBM;
 
 		wstats->qual.qual = local->comms_qual;
 		wstats->qual.level = local->avg_signal;
@@ -59,7 +60,7 @@ static struct iw_statistics *hostap_get_
 		wstats->qual.qual = 0;
 		wstats->qual.level = 0;
 		wstats->qual.noise = 0;
-		wstats->qual.updated = 0;
+		wstats->qual.updated = IW_QUAL_ALL_INVALID;
 	}
 
 	return wstats;
@@ -1894,6 +1895,10 @@ static char * __prism2_translate_scan(lo
 			iwe.u.qual.noise =
 				HFA384X_LEVEL_TO_dBm(le16_to_cpu(scan->anl));
 		}
+		iwe.u.qual.updated = IW_QUAL_LEVEL_UPDATED
+			| IW_QUAL_NOISE_UPDATED
+			| IW_QUAL_QUAL_INVALID
+			| IW_QUAL_DBM;
 		iwe.len = IW_EV_QUAL_LEN;
 		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
 						  IW_EV_QUAL_LEN);
---
0.99.8.GIT


--- NEW FILE 0265-hostap-Use-GFP_ATOMIC-to-get-rid-of-weird-might_sleep-issue.txt ---
Subject: [PATCH] hostap: Use GFP_ATOMIC to get rid of weird might_sleep issue
From: Jean Tourrilhes <jt at hpl.hp.com>
Date: 1127537940 -0700

	This is the trace I got :
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap_ioctl.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: d1161f1c5523e9720f9bc58adf3b7495a5b1ac62
a9d12b9a4afcfa2cb6f6e76beb4f185a9177c98e
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index dd98172..1764563 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1935,7 +1935,7 @@ static char * __prism2_translate_scan(lo
 	}
 
 	/* TODO: add BeaconInt,resp_rate,atim into BSS table */
-	buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_KERNEL);
+	buf = kmalloc(MAX_WPA_IE_LEN * 2 + 30, GFP_ATOMIC);
 	if (buf && scan) {
 		memset(&iwe, 0, sizeof(iwe));
 		iwe.cmd = IWEVCUSTOM;
---
0.99.8.GIT


--- NEW FILE 0266-hostap-Remove-iwe_stream_add_event-kludge.txt ---
Subject: [PATCH] hostap: Remove iwe_stream_add_event kludge
From: Jean Tourrilhes <jt at hpl.hp.com>
Date: 1127537941 -0700

Now that we are compiling with -fno-strict-aliasing (this is the
kernel default), we can drop the following kludge for
iwe_stream_add_event().

Signed-off-by: Jouni Malinen <jkmaline at cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap_ioctl.c |   12 ------------
 1 files changed, 0 insertions(+), 12 deletions(-)

applies-to: ec30834a9f39a737d2f9d01d5c5b561015265ad1
596ff2e7c8db39c700e277f0bc267244be253f5b
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 1764563..53f5246 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -1828,13 +1828,6 @@ static char * __prism2_translate_scan(lo
 	iwe.cmd = SIOCGIWAP;
 	iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
 	memcpy(iwe.u.ap_addr.sa_data, bssid, ETH_ALEN);
-	/* FIX:
-	 * I do not know how this is possible, but iwe_stream_add_event
-	 * seems to re-order memcpy execution so that len is set only
-	 * after copying.. Pre-setting len here "fixes" this, but real
-	 * problems should be solved (after which these iwe.len
-	 * settings could be removed from this function). */
-	iwe.len = IW_EV_ADDR_LEN;
 	current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
 					  IW_EV_ADDR_LEN);
 
@@ -1844,7 +1837,6 @@ static char * __prism2_translate_scan(lo
 	iwe.cmd = SIOCGIWESSID;
 	iwe.u.data.length = ssid_len;
 	iwe.u.data.flags = 1;
-	iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
 	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, ssid);
 
 	memset(&iwe, 0, sizeof(iwe));
@@ -1860,7 +1852,6 @@ static char * __prism2_translate_scan(lo
 			iwe.u.mode = IW_MODE_MASTER;
 		else
 			iwe.u.mode = IW_MODE_ADHOC;
-		iwe.len = IW_EV_UINT_LEN;
 		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
 						  IW_EV_UINT_LEN);
 	}
@@ -1878,7 +1869,6 @@ static char * __prism2_translate_scan(lo
 	if (chan > 0) {
 		iwe.u.freq.m = freq_list[le16_to_cpu(chan - 1)] * 100000;
 		iwe.u.freq.e = 1;
-		iwe.len = IW_EV_FREQ_LEN;
 		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
 						  IW_EV_FREQ_LEN);
 	}
@@ -1899,7 +1889,6 @@ static char * __prism2_translate_scan(lo
 			| IW_QUAL_NOISE_UPDATED
 			| IW_QUAL_QUAL_INVALID
 			| IW_QUAL_DBM;
-		iwe.len = IW_EV_QUAL_LEN;
 		current_ev = iwe_stream_add_event(current_ev, end_buf, &iwe,
 						  IW_EV_QUAL_LEN);
 	}
@@ -1911,7 +1900,6 @@ static char * __prism2_translate_scan(lo
 	else
 		iwe.u.data.flags = IW_ENCODE_DISABLED;
 	iwe.u.data.length = 0;
-	iwe.len = IW_EV_POINT_LEN + iwe.u.data.length;
 	current_ev = iwe_stream_add_point(current_ev, end_buf, &iwe, "");
 
 	/* TODO: add SuppRates into BSS table */
---
0.99.8.GIT


--- NEW FILE 0267-Remove-WIRELESS_EXT-ifdefs-from-several-wireless-drivers.txt ---
Subject: [PATCH] Remove WIRELESS_EXT ifdefs from several wireless drivers.
From: Jeff Garzik <jgarzik at pobox.com>
Date: 1127549152 -0400

---

 drivers/net/wireless/airo.c               |   17 ---
 drivers/net/wireless/netwave_cs.c         |  185 -----------------------------
 drivers/net/wireless/prism54/isl_ioctl.c  |   10 --
 drivers/net/wireless/prism54/islpci_dev.c |    4 -
 drivers/net/wireless/prism54/islpci_dev.h |    2 
 drivers/net/wireless/wavelan.c            |    8 -
 drivers/net/wireless/wavelan.p.h          |    4 -
 drivers/net/wireless/wavelan_cs.c         |    8 -
 drivers/net/wireless/wavelan_cs.p.h       |    4 -
 9 files changed, 1 insertions(+), 241 deletions(-)

applies-to: 9f0f0897c0ef74f8d44510c0cc868ee0e314cbdd
e2e965072564e7aad8df963107677a6d22c41767
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 06998c2..a619495 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -1046,7 +1046,6 @@ static WifiCtlHdr wifictlhdr8023 = {
 	}
 };
 
-#ifdef WIRELESS_EXT
 // Frequency list (map channels to frequencies)
 static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
 				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
@@ -1067,7 +1066,6 @@ typedef struct wep_key_t {
 
 /* List of Wireless Handlers (new API) */
 static const struct iw_handler_def	airo_handler_def;
-#endif /* WIRELESS_EXT */
 
 static const char version[] = "airo.c 0.6 (Ben Reed & Javier Achirica)";
 
@@ -1110,10 +1108,8 @@ static irqreturn_t airo_interrupt( int i
 static int airo_thread(void *data);
 static void timer_func( struct net_device *dev );
 static int airo_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
-#ifdef WIRELESS_EXT
 static struct iw_statistics *airo_get_wireless_stats (struct net_device *dev);
 static void airo_read_wireless_stats (struct airo_info *local);
-#endif /* WIRELESS_EXT */
 #ifdef CISCO_EXT
 static int readrids(struct net_device *dev, aironet_ioctl *comp);
 static int writerids(struct net_device *dev, aironet_ioctl *comp);
@@ -1187,12 +1183,10 @@ struct airo_info {
 		int fid;
 	} xmit, xmit11;
 	struct net_device *wifidev;
-#ifdef WIRELESS_EXT
 	struct iw_statistics	wstats;		// wireless stats
 	unsigned long		scan_timestamp;	/* Time started to scan */
 	struct iw_spy_data	spy_data;
 	struct iw_public_data	wireless_data;
-#endif /* WIRELESS_EXT */
 #ifdef MICSUPPORT
 	/* MIC stuff */
 	struct crypto_tfm	*tfm;
@@ -2647,9 +2641,7 @@ static void wifi_setup(struct net_device
 	dev->get_stats = &airo_get_stats;
 	dev->set_mac_address = &airo_set_mac_address;
 	dev->do_ioctl = &airo_ioctl;
-#ifdef WIRELESS_EXT
 	dev->wireless_handlers = &airo_handler_def;
-#endif /* WIRELESS_EXT */
 	dev->change_mtu = &airo_change_mtu;
 	dev->open = &airo_open;
 	dev->stop = &airo_close;
@@ -2675,9 +2667,7 @@ static struct net_device *init_wifidev(s
 	dev->priv = ethdev->priv;
 	dev->irq = ethdev->irq;
 	dev->base_addr = ethdev->base_addr;
-#ifdef WIRELESS_EXT
 	dev->wireless_data = ethdev->wireless_data;
-#endif /* WIRELESS_EXT */
 	memcpy(dev->dev_addr, ethdev->dev_addr, dev->addr_len);
 	err = register_netdev(dev);
 	if (err<0) {
@@ -2755,11 +2745,9 @@ static struct net_device *_init_airo_car
 	dev->set_multicast_list = &airo_set_multicast_list;
 	dev->set_mac_address = &airo_set_mac_address;
 	dev->do_ioctl = &airo_ioctl;
-#ifdef WIRELESS_EXT
 	dev->wireless_handlers = &airo_handler_def;
 	ai->wireless_data.spy_data = &ai->spy_data;
 	dev->wireless_data = &ai->wireless_data;
-#endif /* WIRELESS_EXT */
 	dev->change_mtu = &airo_change_mtu;
 	dev->open = &airo_open;
 	dev->stop = &airo_close;
@@ -5598,7 +5586,6 @@ static void __exit airo_cleanup_module( 
 	remove_proc_entry("aironet", proc_root_driver);
 }
 
-#ifdef WIRELESS_EXT
 /*
  * Initial Wireless Extension code for Aironet driver by :
  *	Jean Tourrilhes <jt at hpl.hp.com> - HPL - 17 November 00
@@ -7107,8 +7094,6 @@ static const struct iw_handler_def	airo_
 	.get_wireless_stats = airo_get_wireless_stats,
 };
 
-#endif /* WIRELESS_EXT */
-
 /*
  * This defines the configuration part of the Wireless Extensions
  * Note : irq and spinlock protection will occur in the subroutines
@@ -7187,7 +7172,6 @@ static int airo_ioctl(struct net_device 
 	return rc;
 }
 
-#ifdef WIRELESS_EXT
 /*
  * Get the Wireless stats out of the driver
  * Note : irq and spinlock protection will occur in the subroutines
@@ -7260,7 +7244,6 @@ static struct iw_statistics *airo_get_wi
 
 	return &local->wstats;
 }
-#endif /* WIRELESS_EXT */
 
 #ifdef CISCO_EXT
 /*
diff --git a/drivers/net/wireless/netwave_cs.c b/drivers/net/wireless/netwave_cs.c
index ca6c03c..92793b9 100644
--- a/drivers/net/wireless/netwave_cs.c
+++ b/drivers/net/wireless/netwave_cs.c
@@ -57,9 +57,7 @@
 #include <linux/bitops.h>
 #ifdef CONFIG_NET_RADIO
 #include <linux/wireless.h>
-#if WIRELESS_EXT > 12
 #include <net/iw_handler.h>
-#endif	/* WIRELESS_EXT > 12 */
 #endif
 
 #include <pcmcia/cs_types.h>
@@ -225,10 +223,7 @@ static void update_stats(struct net_devi
 static struct net_device_stats *netwave_get_stats(struct net_device *dev);
 
 /* Wireless extensions */
-#ifdef WIRELESS_EXT
 static struct iw_statistics* netwave_get_wireless_stats(struct net_device *dev);
-#endif
-static int netwave_ioctl(struct net_device *, struct ifreq *, int);
 
 static void set_multicast_list(struct net_device *dev);
 
@@ -260,26 +255,7 @@ static dev_link_t *dev_list;
    because they generally can't be allocated dynamically.
 */
 
-#if WIRELESS_EXT <= 12
-/* Wireless extensions backward compatibility */
-
-/* Part of iw_handler prototype we need */
-struct iw_request_info
-{
-	__u16		cmd;		/* Wireless Extension command */
-	__u16		flags;		/* More to come ;-) */
-};
-
-/* Wireless Extension Backward compatibility - Jean II
- * If the new wireless device private ioctl range is not defined,
- * default to standard device private ioctl range */
-#ifndef SIOCIWFIRSTPRIV
-#define SIOCIWFIRSTPRIV	SIOCDEVPRIVATE
-#endif /* SIOCIWFIRSTPRIV */
-
-#else	/* WIRELESS_EXT <= 12 */
 static const struct iw_handler_def	netwave_handler_def;
-#endif	/* WIRELESS_EXT <= 12 */
 
 #define SIOCGIPSNAP	SIOCIWFIRSTPRIV	+ 1	/* Site Survey Snapshot */
 
@@ -319,9 +295,7 @@ typedef struct netwave_private {
     struct timer_list      watchdog;	/* To avoid blocking state */
     struct site_survey     nss;
     struct net_device_stats stats;
-#ifdef WIRELESS_EXT
     struct iw_statistics   iw_stats;    /* Wireless stats */
-#endif
 } netwave_private;
 
 #ifdef NETWAVE_STATS
@@ -353,7 +327,6 @@ static inline void wait_WOC(unsigned int
     while ((inb(iobase + NETWAVE_REG_ASR) & 0x8) != 0x8) ; 
 }
 
-#ifdef WIRELESS_EXT
 static void netwave_snapshot(netwave_private *priv, u_char __iomem *ramBase, 
 			     kio_addr_t iobase) {
     u_short resultBuffer;
@@ -376,9 +349,7 @@ static void netwave_snapshot(netwave_pri
 		      sizeof(struct site_survey)); 
     } 
 }
-#endif
 
-#ifdef WIRELESS_EXT
 /*
  * Function netwave_get_wireless_stats (dev)
  *
@@ -411,7 +382,6 @@ static struct iw_statistics *netwave_get
     
     return &priv->iw_stats;
 }
-#endif
 
 /*
  * Function netwave_attach (void)
@@ -471,13 +441,7 @@ static dev_link_t *netwave_attach(void)
     dev->get_stats  = &netwave_get_stats;
     dev->set_multicast_list = &set_multicast_list;
     /* wireless extensions */
-#if WIRELESS_EXT <= 16
-    dev->get_wireless_stats = &netwave_get_wireless_stats;
-#endif /* WIRELESS_EXT <= 16 */
-#if WIRELESS_EXT > 12
     dev->wireless_handlers = (struct iw_handler_def *)&netwave_handler_def;
-#endif /* WIRELESS_EXT > 12 */
-    dev->do_ioctl = &netwave_ioctl;
 
     dev->tx_timeout = &netwave_watchdog;
     dev->watchdog_timeo = TX_TIMEOUT;
@@ -576,13 +540,8 @@ static int netwave_set_nwid(struct net_d
 	/* Disable interrupts & save flags */
 	spin_lock_irqsave(&priv->spinlock, flags);
 
-#if WIRELESS_EXT > 8
 	if(!wrqu->nwid.disabled) {
 	    domain = wrqu->nwid.value;
-#else	/* WIRELESS_EXT > 8 */
-	if(wrqu->nwid.on) {
-	    domain = wrqu->nwid.nwid;
-#endif	/* WIRELESS_EXT > 8 */
 	    printk( KERN_DEBUG "Setting domain to 0x%x%02x\n", 
 		    (domain >> 8) & 0x01, domain & 0xff);
 	    wait_WOC(iobase);
@@ -606,15 +565,9 @@ static int netwave_get_nwid(struct net_d
 			    union iwreq_data *wrqu,
 			    char *extra)
 {
-#if WIRELESS_EXT > 8
 	wrqu->nwid.value = domain;
 	wrqu->nwid.disabled = 0;
 	wrqu->nwid.fixed = 1;
-#else	/* WIRELESS_EXT > 8 */
-	wrqu->nwid.nwid = domain;
-	wrqu->nwid.on = 1;
-#endif	/* WIRELESS_EXT > 8 */
-
 	return 0;
 }
 
@@ -657,17 +610,11 @@ static int netwave_get_scramble(struct n
 {
 	key[1] = scramble_key & 0xff;
 	key[0] = (scramble_key>>8) & 0xff;
-#if WIRELESS_EXT > 8
 	wrqu->encoding.flags = IW_ENCODE_ENABLED;
 	wrqu->encoding.length = 2;
-#else /* WIRELESS_EXT > 8 */
-	wrqu->encoding.method = 1;
-#endif	/* WIRELESS_EXT > 8 */
-
 	return 0;
 }
 
-#if WIRELESS_EXT > 8
 /*
  * Wireless Handler : get mode
  */
@@ -683,7 +630,6 @@ static int netwave_get_mode(struct net_d
 
 	return 0;
 }
-#endif	/* WIRELESS_EXT > 8 */
 
 /*
  * Wireless Handler : get range info
@@ -702,11 +648,9 @@ static int netwave_get_range(struct net_
 	/* Set all the info we don't care or don't know about to zero */
 	memset(range, 0, sizeof(struct iw_range));
 
-#if WIRELESS_EXT > 10
 	/* Set the Wireless Extension versions */
 	range->we_version_compiled = WIRELESS_EXT;
 	range->we_version_source = 9;	/* Nothing for us in v10 and v11 */
-#endif /* WIRELESS_EXT > 10 */
 		   
 	/* Set information in the range struct */
 	range->throughput = 450 * 1000;	/* don't argue on this ! */
@@ -720,16 +664,12 @@ static int netwave_get_range(struct net_
 	range->max_qual.level = 255;
 	range->max_qual.noise = 0;
 		   
-#if WIRELESS_EXT > 7
 	range->num_bitrates = 1;
 	range->bitrate[0] = 1000000;	/* 1 Mb/s */
-#endif /* WIRELESS_EXT > 7 */
 
-#if WIRELESS_EXT > 8
 	range->encoding_size[0] = 2;		/* 16 bits scrambling */
 	range->num_encoding_sizes = 1;
 	range->max_encoding_tokens = 1;	/* Only one key possible */
-#endif /* WIRELESS_EXT > 8 */
 
 	return ret;
 }
@@ -775,8 +715,6 @@ static const struct iw_priv_args netwave
     "getsitesurvey" },
 };
 
-#if WIRELESS_EXT > 12
-
 static const iw_handler		netwave_handler[] =
 {
 	NULL,				/* SIOCSIWNAME */
@@ -839,131 +777,8 @@ static const struct iw_handler_def	netwa
 	.standard	= (iw_handler *) netwave_handler,
 	.private	= (iw_handler *) netwave_private_handler,
 	.private_args	= (struct iw_priv_args *) netwave_private_args,
-#if WIRELESS_EXT > 16
 	.get_wireless_stats = netwave_get_wireless_stats,
-#endif /* WIRELESS_EXT > 16 */
 };
-#endif /* WIRELESS_EXT > 12 */
-
-/*
- * Function netwave_ioctl (dev, rq, cmd)
- *
- *     Perform ioctl : config & info stuff
- *     This is the stuff that are treated the wireless extensions (iwconfig)
- *
- */
-static int netwave_ioctl(struct net_device *dev, /* ioctl device */
-			 struct ifreq *rq,	 /* Data passed */
-			 int	cmd)	     /* Ioctl number */
-{
-    int			ret = 0;
-#ifdef WIRELESS_EXT
-#if WIRELESS_EXT <= 12
-    struct iwreq *wrq = (struct iwreq *) rq;
-#endif
-#endif
-	
-    DEBUG(0, "%s: ->netwave_ioctl(cmd=0x%X)\n", dev->name, cmd);
-	
-    /* Look what is the request */
-    switch(cmd) {
-	/* --------------- WIRELESS EXTENSIONS --------------- */
-#ifdef WIRELESS_EXT
-#if WIRELESS_EXT <= 12
-    case SIOCGIWNAME:
-	netwave_get_name(dev, NULL, &(wrq->u), NULL);
-	break;
-    case SIOCSIWNWID:
-	ret = netwave_set_nwid(dev, NULL, &(wrq->u), NULL);
-	break;
-    case SIOCGIWNWID:
-	ret = netwave_get_nwid(dev, NULL, &(wrq->u), NULL);
-	break;
-#if WIRELESS_EXT > 8	/* Note : The API did change... */
-    case SIOCGIWENCODE:
-	/* Get scramble key */
-	if(wrq->u.encoding.pointer != (caddr_t) 0)
-	  {
-	    char	key[2];
-	    ret = netwave_get_scramble(dev, NULL, &(wrq->u), key);
-	    if(copy_to_user(wrq->u.encoding.pointer, key, 2))
-	      ret = -EFAULT;
-	  }
-	break;
-    case SIOCSIWENCODE:
-	/* Set  scramble key */
-	if(wrq->u.encoding.pointer != (caddr_t) 0)
-	  {
-	    char	key[2];
-	    if(copy_from_user(key, wrq->u.encoding.pointer, 2))
-	      {
-		ret = -EFAULT;
-		break;
-	      }
-	    ret = netwave_set_scramble(dev, NULL, &(wrq->u), key);
-	  }
-	break;
-    case SIOCGIWMODE:
-	/* Mode of operation */
-	ret = netwave_get_mode(dev, NULL, &(wrq->u), NULL);
-	break;
-#else /* WIRELESS_EXT > 8 */
-    case SIOCGIWENCODE:
-	/* Get scramble key */
-	ret = netwave_get_scramble(dev, NULL, &(wrq->u),
-				   (char *) &wrq->u.encoding.code);
-	break;
-    case SIOCSIWENCODE:
-	/* Set  scramble key */
-	ret = netwave_set_scramble(dev, NULL, &(wrq->u),
-				   (char *) &wrq->u.encoding.code);
-	break;
-#endif /* WIRELESS_EXT > 8 */
-   case SIOCGIWRANGE:
-       /* Basic checking... */
-       if(wrq->u.data.pointer != (caddr_t) 0) {
-           struct iw_range range;
-	   ret = netwave_get_range(dev, NULL, &(wrq->u), (char *) &range);
-	   if (copy_to_user(wrq->u.data.pointer, &range,
-			    sizeof(struct iw_range)))
-	       ret = -EFAULT;
-       }
-       break;
-    case SIOCGIWPRIV:
-	/* Basic checking... */
-	if(wrq->u.data.pointer != (caddr_t) 0) {
-	    /* Set the number of ioctl available */
-	    wrq->u.data.length = sizeof(netwave_private_args) / sizeof(netwave_private_args[0]);
-			
-	    /* Copy structure to the user buffer */
-	    if(copy_to_user(wrq->u.data.pointer,
-			    (u_char *) netwave_private_args,
-			    sizeof(netwave_private_args)))
-	      ret = -EFAULT;
-	} 
-	break;
-    case SIOCGIPSNAP:
-	if(wrq->u.data.pointer != (caddr_t) 0) {
-	    char buffer[sizeof( struct site_survey)];
-	    ret = netwave_get_snap(dev, NULL, &(wrq->u), buffer);
-	    /* Copy structure to the user buffer */
-	    if(copy_to_user(wrq->u.data.pointer, 
-			    buffer,
-			    sizeof( struct site_survey)))
-	      {
-		printk(KERN_DEBUG "Bad buffer!\n");
-		break;
-	      }
-	}
-	break;
-#endif /* WIRELESS_EXT <= 12 */
-#endif /* WIRELESS_EXT */
-    default:
-	ret = -EOPNOTSUPP;
-    }
-	
-    return ret;
-}
 
 /*
  * Function netwave_pcmcia_config (link)
diff --git a/drivers/net/wireless/prism54/isl_ioctl.c b/drivers/net/wireless/prism54/isl_ioctl.c
index 9a8790e..5c1a1ad 100644
--- a/drivers/net/wireless/prism54/isl_ioctl.c
+++ b/drivers/net/wireless/prism54/isl_ioctl.c
@@ -462,14 +462,12 @@ prism54_get_range(struct net_device *nde
 	/* txpower is supported in dBm's */
 	range->txpower_capa = IW_TXPOW_DBM;
 
-#if WIRELESS_EXT > 16
 	/* Event capability (kernel + driver) */
 	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
 	IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
 	IW_EVENT_CAPA_MASK(SIOCGIWAP));
 	range->event_capa[1] = IW_EVENT_CAPA_K_1;
 	range->event_capa[4] = IW_EVENT_CAPA_MASK(IWEVCUSTOM);
-#endif /* WIRELESS_EXT > 16 */
 
 	if (islpci_get_state(priv) < PRV_STATE_INIT)
 		return 0;
@@ -693,14 +691,13 @@ prism54_get_scan(struct net_device *ndev
 						   extra + dwrq->length,
 						   &(bsslist->bsslist[i]),
 						   noise);
-#if WIRELESS_EXT > 16
+
 		/* Check if there is space for one more entry */
 		if((extra + dwrq->length - current_ev) <= IW_EV_ADDR_LEN) {
 			/* Ask user space to try again with a bigger buffer */
 			rvalue = -E2BIG;
 			break;
 		}
-#endif /* WIRELESS_EXT > 16 */
 	}
 
 	kfree(bsslist);
@@ -2727,12 +2724,7 @@ const struct iw_handler_def prism54_hand
 	.standard = (iw_handler *) prism54_handler,
 	.private = (iw_handler *) prism54_private_handler,
 	.private_args = (struct iw_priv_args *) prism54_private_args,
-#if WIRELESS_EXT > 16
 	.get_wireless_stats = prism54_get_wireless_stats,
-#endif /* WIRELESS_EXT > 16 */
-#if WIRELESS_EXT == 16
-	.spy_offset = offsetof(islpci_private, spy_data),
-#endif /* WIRELESS_EXT == 16 */
 };
 
 /* For wpa_supplicant */
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 10cce51..6c9584a 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -837,13 +837,9 @@ islpci_setup(struct pci_dev *pdev)
 	priv->ndev->type = (priv->iw_mode == IW_MODE_MONITOR) ?
 		priv->monitor_type : ARPHRD_ETHER;
 
-#if WIRELESS_EXT > 16
 	/* Add pointers to enable iwspy support. */
 	priv->wireless_data.spy_data = &priv->spy_data;
 	ndev->wireless_data = &priv->wireless_data;
-#else  /* WIRELESS_EXT > 16 */
-	ndev->get_wireless_stats = &prism54_get_wireless_stats;
-#endif /* WIRELESS_EXT > 16 */
 
 	/* save the start and end address of the PCI memory area */
 	ndev->mem_start = (unsigned long) priv->device_base;
diff --git a/drivers/net/wireless/prism54/islpci_dev.h b/drivers/net/wireless/prism54/islpci_dev.h
index 32a1019..efbed43 100644
--- a/drivers/net/wireless/prism54/islpci_dev.h
+++ b/drivers/net/wireless/prism54/islpci_dev.h
@@ -100,9 +100,7 @@ typedef struct {
 
 	struct iw_spy_data spy_data; /* iwspy support */
 
-#if WIRELESS_EXT > 16
 	struct iw_public_data wireless_data;
-#endif /* WIRELESS_EXT > 16 */
 
 	int monitor_type; /* ARPHRD_IEEE80211 or ARPHRD_IEEE80211_PRISM */
 
diff --git a/drivers/net/wireless/wavelan.c b/drivers/net/wireless/wavelan.c
index 7a5e20a..b0d8b5b 100644
--- a/drivers/net/wireless/wavelan.c
+++ b/drivers/net/wireless/wavelan.c
@@ -430,7 +430,6 @@ static void fee_read(unsigned long ioadd
 	}
 }
 
-#ifdef WIRELESS_EXT		/* if the wireless extension exists in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -514,7 +513,6 @@ static void fee_write(unsigned long ioad
 	fee_wait(ioaddr, 10, 100);
 #endif				/* EEPROM_IS_PROTECTED */
 }
-#endif				/* WIRELESS_EXT */
 
 /************************ I82586 SUBROUTINES *************************/
 /*
@@ -973,11 +971,9 @@ static void wv_mmc_show(struct net_devic
 	mmc_read(ioaddr, 0, (u8 *) & m, sizeof(m));
 	mmc_out(ioaddr, mmwoff(0, mmw_freeze), 0);
 
-#ifdef WIRELESS_EXT		/* if wireless extension exists in the kernel */
 	/* Don't forget to update statistics */
 	lp->wstats.discard.nwid +=
 	    (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-#endif				/* WIRELESS_EXT */
 
 	printk(KERN_DEBUG "##### WaveLAN modem status registers: #####\n");
 #ifdef DEBUG_SHOW_UNUSED
@@ -1499,7 +1495,6 @@ static int wavelan_set_mac_address(struc
 }
 #endif				/* SET_MAC_ADDRESS */
 
-#ifdef WIRELESS_EXT		/* if wireless extensions exist in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -2473,7 +2468,6 @@ static iw_stats *wavelan_get_wireless_st
 #endif
 	return &lp->wstats;
 }
-#endif				/* WIRELESS_EXT */
 
 /************************* PACKET RECEPTION *************************/
 /*
@@ -4194,11 +4188,9 @@ static int __init wavelan_config(struct 
 	dev->set_mac_address = &wavelan_set_mac_address;
 #endif				/* SET_MAC_ADDRESS */
 
-#ifdef WIRELESS_EXT		/* if wireless extension exists in the kernel */
 	dev->wireless_handlers = &wavelan_handler_def;
 	lp->wireless_data.spy_data = &lp->spy_data;
 	dev->wireless_data = &lp->wireless_data;
-#endif
 
 	dev->mtu = WAVELAN_MTU;
 
diff --git a/drivers/net/wireless/wavelan.p.h b/drivers/net/wireless/wavelan.p.h
index 509ff22..166e28b 100644
--- a/drivers/net/wireless/wavelan.p.h
+++ b/drivers/net/wireless/wavelan.p.h
@@ -409,11 +409,9 @@
 #define MULTICAST_AVOID		/* Avoid extra multicast (I'm sceptical). */
 #undef SET_MAC_ADDRESS		/* Experimental */
 
-#ifdef WIRELESS_EXT	/* If wireless extensions exist in the kernel */
 /* Warning:  this stuff will slow down the driver. */
 #define WIRELESS_SPY		/* Enable spying addresses. */
 #undef HISTOGRAM		/* Enable histogram of signal level. */
-#endif
 
 /****************************** DEBUG ******************************/
 
@@ -506,12 +504,10 @@ struct net_local
   u_short	tx_first_free;
   u_short	tx_first_in_use;
 
-#ifdef WIRELESS_EXT
   iw_stats	wstats;		/* Wireless-specific statistics */
 
   struct iw_spy_data	spy_data;
   struct iw_public_data	wireless_data;
-#endif
 
 #ifdef HISTOGRAM
   int		his_number;		/* number of intervals */
diff --git a/drivers/net/wireless/wavelan_cs.c b/drivers/net/wireless/wavelan_cs.c
index 183c473..4b3c98f 100644
--- a/drivers/net/wireless/wavelan_cs.c
+++ b/drivers/net/wireless/wavelan_cs.c
@@ -415,7 +415,6 @@ fee_read(u_long		base,	/* i/o port of th
     }
 }
 
-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -500,7 +499,6 @@ fee_write(u_long	base,	/* i/o port of th
   fee_wait(base, 10, 100);
 #endif	/* EEPROM_IS_PROTECTED */
 }
-#endif	/* WIRELESS_EXT */
 
 /******************* WaveLAN Roaming routines... ********************/
 
@@ -1161,10 +1159,8 @@ wv_mmc_show(struct net_device *	dev)
   mmc_read(base, 0, (u_char *)&m, sizeof(m));
   mmc_out(base, mmwoff(0, mmw_freeze), 0);
 
-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
   /* Don't forget to update statistics */
   lp->wstats.discard.nwid += (m.mmr_wrong_nwid_h << 8) | m.mmr_wrong_nwid_l;
-#endif	/* WIRELESS_EXT */
 
   spin_unlock_irqrestore(&lp->spinlock, flags);
 
@@ -1550,7 +1546,6 @@ wavelan_set_mac_address(struct net_devic
 }
 #endif	/* SET_MAC_ADDRESS */
 
-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
 
 /*------------------------------------------------------------------*/
 /*
@@ -2793,7 +2788,6 @@ wavelan_get_wireless_stats(struct net_de
 #endif
   return &lp->wstats;
 }
-#endif	/* WIRELESS_EXT */
 
 /************************* PACKET RECEPTION *************************/
 /*
@@ -4679,11 +4673,9 @@ wavelan_attach(void)
   dev->watchdog_timeo	= WATCHDOG_JIFFIES;
   SET_ETHTOOL_OPS(dev, &ops);
 
-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
   dev->wireless_handlers = &wavelan_handler_def;
   lp->wireless_data.spy_data = &lp->spy_data;
   dev->wireless_data = &lp->wireless_data;
-#endif
 
   /* Other specific data */
   dev->mtu = WAVELAN_MTU;
diff --git a/drivers/net/wireless/wavelan_cs.p.h b/drivers/net/wireless/wavelan_cs.p.h
index 01d882b..724a715 100644
--- a/drivers/net/wireless/wavelan_cs.p.h
+++ b/drivers/net/wireless/wavelan_cs.p.h
@@ -472,11 +472,9 @@
 #define MULTICAST_AVOID		/* Avoid extra multicast (I'm sceptical) */
 #undef SET_MAC_ADDRESS		/* Experimental */
 
-#ifdef WIRELESS_EXT	/* If wireless extension exist in the kernel */
 /* Warning : these stuff will slow down the driver... */
 #define WIRELESS_SPY		/* Enable spying addresses */
 #undef HISTOGRAM		/* Enable histogram of sig level... */
-#endif
 
 /****************************** DEBUG ******************************/
 
@@ -624,12 +622,10 @@ struct net_local
   int   	rfp;		/* Last DMA machine receive pointer */
   int		overrunning;	/* Receiver overrun flag */
 
-#ifdef WIRELESS_EXT
   iw_stats	wstats;		/* Wireless specific stats */
 
   struct iw_spy_data	spy_data;
   struct iw_public_data	wireless_data;
-#endif
 
 #ifdef HISTOGRAM
   int		his_number;		/* Number of intervals */
---
0.99.8.GIT


--- NEW FILE 0268-wireless-airo-remove-needed-dma_addr_t-obfuscation.txt ---
Subject: [PATCH] [wireless airo] remove needed dma_addr_t obfuscation
From: Jeff Garzik <jgarzik at pobox.com>
Date: 1127549344 -0400

Fixes bus address truncation bug for certain configs.

---

 drivers/net/wireless/airo.c |   13 +++++++------
 1 files changed, 7 insertions(+), 6 deletions(-)

applies-to: 92667c7ec98f96308f4eefd4ec3c1bdfbb5acd93
2759c8d536efe3b853867f345627d89fb64c37af
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index a619495..746456c 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2521,7 +2521,8 @@ static int mpi_map_card(struct airo_info
 	unsigned long mem_start, mem_len, aux_start, aux_len;
 	int rc = -1;
 	int i;
-	unsigned char *busaddroff,*vpackoff;
+	dma_addr_t busaddroff;
+	unsigned char *vpackoff;
 	unsigned char __iomem *pciaddroff;
 
 	mem_start = pci_resource_start(pci, 1);
@@ -2564,7 +2565,7 @@ static int mpi_map_card(struct airo_info
 	/*
 	 * Setup descriptor RX, TX, CONFIG
 	 */
-	busaddroff = (unsigned char *)ai->shared_dma;
+	busaddroff = ai->shared_dma;
 	pciaddroff = ai->pciaux + AUX_OFFSET;
 	vpackoff   = ai->shared;
 
@@ -2573,7 +2574,7 @@ static int mpi_map_card(struct airo_info
 		ai->rxfids[i].pending = 0;
 		ai->rxfids[i].card_ram_off = pciaddroff;
 		ai->rxfids[i].virtual_host_addr = vpackoff;
-		ai->rxfids[i].rx_desc.host_addr = (dma_addr_t) busaddroff;
+		ai->rxfids[i].rx_desc.host_addr = busaddroff;
 		ai->rxfids[i].rx_desc.valid = 1;
 		ai->rxfids[i].rx_desc.len = PKTSIZE;
 		ai->rxfids[i].rx_desc.rdy = 0;
@@ -2588,7 +2589,7 @@ static int mpi_map_card(struct airo_info
 		ai->txfids[i].card_ram_off = pciaddroff;
 		ai->txfids[i].virtual_host_addr = vpackoff;
 		ai->txfids[i].tx_desc.valid = 1;
-		ai->txfids[i].tx_desc.host_addr = (dma_addr_t) busaddroff;
+		ai->txfids[i].tx_desc.host_addr = busaddroff;
 		memcpy(ai->txfids[i].virtual_host_addr,
 			&wifictlhdr8023, sizeof(wifictlhdr8023));
 
@@ -2601,8 +2602,8 @@ static int mpi_map_card(struct airo_info
 	/* Rid descriptor setup */
 	ai->config_desc.card_ram_off = pciaddroff;
 	ai->config_desc.virtual_host_addr = vpackoff;
-	ai->config_desc.rid_desc.host_addr = (dma_addr_t) busaddroff;
-	ai->ridbus = (dma_addr_t)busaddroff;
+	ai->config_desc.rid_desc.host_addr = busaddroff;
+	ai->ridbus = busaddroff;
 	ai->config_desc.rid_desc.rid = 0;
 	ai->config_desc.rid_desc.len = RIDSIZE;
 	ai->config_desc.rid_desc.valid = 1;
---
0.99.8.GIT


--- NEW FILE 0345-hostap-Remove-hw-specific-dev_open-close-handlers.txt ---
Subject: [PATCH] hostap: Remove hw specific dev_open/close handlers
From: Jouni Malinen <jkmaline at cc.hut.fi>
Date: 1128298738 -0700

Host AP driver used hardware model specific dev_open/close handlers
that were called on dev_open/close if the hardware driver had
registered the handler. These were only used for hostap_cs and only
for tracking whether any of the netdevs were UP. This information is
already available from local->num_dev_open, so there is not need for
the special open/close handler.

Let's get rid of these handlers. In addition to cleaning up the code,
this fixes a module refcounting issue for hostap_cs where ejecting the
card while any of the netdevs were open did not decrement refcount
properly.

Signed-off-by: Jouni Malinen <jkmaline at cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap.c      |    6 ----
 drivers/net/wireless/hostap/hostap_cs.c   |   45 ++++++-----------------------
 drivers/net/wireless/hostap/hostap_pci.c  |    2 -
 drivers/net/wireless/hostap/hostap_plx.c  |    2 -
 drivers/net/wireless/hostap/hostap_wlan.h |    2 -
 5 files changed, 10 insertions(+), 47 deletions(-)

applies-to: e8dc66c8c5e2e5dbea9629f1405cdf9bada79985
bab76198b3111bd0328be3c1fa208237eb12f86e
diff --git a/drivers/net/wireless/hostap/hostap.c b/drivers/net/wireless/hostap/hostap.c
index e7f5821..6a96cd9 100644
--- a/drivers/net/wireless/hostap/hostap.c
+++ b/drivers/net/wireless/hostap/hostap.c
@@ -716,9 +716,6 @@ static int prism2_close(struct net_devic
 		hostap_deauth_all_stas(dev, local->ap, 1);
 #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */
 
-	if (local->func->dev_close && local->func->dev_close(local))
-		return 0;
-
 	if (dev == local->dev) {
 		local->func->hw_shutdown(dev, HOSTAP_HW_ENABLE_CMDCOMPL);
 	}
@@ -766,9 +763,6 @@ static int prism2_open(struct net_device
 	    local->hw_downloading)
 		return -ENODEV;
 
-	if (local->func->dev_open && local->func->dev_open(local))
-		return 1;
-
 	if (!try_module_get(local->hw_module))
 		return -ENODEV;
 	local->num_dev_open++;
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index faa83ba..23bcc51 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -492,42 +492,10 @@ static void prism2_pccard_genesis_reset(
 }
 
 
-static int prism2_pccard_dev_open(local_info_t *local)
-{
-	struct hostap_cs_priv *hw_priv = local->hw_priv;
-	hw_priv->link->open++;
-	return 0;
-}
-
-
-static int prism2_pccard_dev_close(local_info_t *local)
-{
-	struct hostap_cs_priv *hw_priv;
-
-	if (local == NULL || local->hw_priv == NULL)
-		return 1;
-	hw_priv = local->hw_priv;
-	if (hw_priv->link == NULL)
-		return 1;
-
-	if (!hw_priv->link->open) {
-		printk(KERN_WARNING "%s: prism2_pccard_dev_close(): "
-		       "link not open?!\n", local->dev->name);
-		return 1;
-	}
-
-	hw_priv->link->open--;
-
-	return 0;
-}
-
-
 static struct prism2_helper_functions prism2_pccard_funcs =
 {
 	.card_present	= prism2_pccard_card_present,
 	.cor_sreset	= prism2_pccard_cor_sreset,
-	.dev_open	= prism2_pccard_dev_open,
-	.dev_close	= prism2_pccard_dev_close,
 	.genesis_reset	= prism2_pccard_genesis_reset,
 	.hw_type	= HOSTAP_HW_PCCARD,
 };
@@ -883,6 +851,13 @@ static int prism2_event(event_t event, i
 {
 	dev_link_t *link = args->client_data;
 	struct net_device *dev = (struct net_device *) link->priv;
+	int dev_open = 0;
+
+	if (link->state & DEV_CONFIG) {
+		struct hostap_interface *iface = netdev_priv(dev);
+		if (iface && iface->local)
+			dev_open = iface->local->num_dev_open > 0;
+	}
 
 	switch (event) {
 	case CS_EVENT_CARD_INSERTION:
@@ -911,7 +886,7 @@ static int prism2_event(event_t event, i
 	case CS_EVENT_RESET_PHYSICAL:
 		PDEBUG(DEBUG_EXTRA, "%s: CS_EVENT_RESET_PHYSICAL\n", dev_info);
 		if (link->state & DEV_CONFIG) {
-			if (link->open) {
+			if (dev_open) {
 				netif_stop_queue(dev);
 				netif_device_detach(dev);
 			}
@@ -931,8 +906,8 @@ static int prism2_event(event_t event, i
 			pcmcia_request_configuration(link->handle,
 						     &link->conf);
 			prism2_hw_shutdown(dev, 1);
-			prism2_hw_config(dev, link->open ? 0 : 1);
-			if (link->open) {
+			prism2_hw_config(dev, dev_open ? 0 : 1);
+			if (dev_open) {
 				netif_device_attach(dev);
 				netif_start_queue(dev);
 			}
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index b9254f7..594cc29 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -277,8 +277,6 @@ static struct prism2_helper_functions pr
 {
 	.card_present	= NULL,
 	.cor_sreset	= prism2_pci_cor_sreset,
-	.dev_open	= NULL,
-	.dev_close	= NULL,
 	.genesis_reset	= prism2_pci_genesis_reset,
 	.hw_type	= HOSTAP_HW_PCI,
 };
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 1abebdf..85d3f8a 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -328,8 +328,6 @@ static struct prism2_helper_functions pr
 {
 	.card_present	= NULL,
 	.cor_sreset	= prism2_plx_cor_sreset,
-	.dev_open	= NULL,
-	.dev_close	= NULL,
 	.genesis_reset	= prism2_plx_genesis_reset,
 	.hw_type	= HOSTAP_HW_PLX,
 };
diff --git a/drivers/net/wireless/hostap/hostap_wlan.h b/drivers/net/wireless/hostap/hostap_wlan.h
index cc061e1..cfd8015 100644
--- a/drivers/net/wireless/hostap/hostap_wlan.h
+++ b/drivers/net/wireless/hostap/hostap_wlan.h
@@ -552,8 +552,6 @@ struct prism2_helper_functions {
 	 * (hostap_{cs,plx,pci}.c */
 	int (*card_present)(local_info_t *local);
 	void (*cor_sreset)(local_info_t *local);
-	int (*dev_open)(local_info_t *local);
-	int (*dev_close)(local_info_t *local);
 	void (*genesis_reset)(local_info_t *local, int hcr);
 
 	/* the following functions are from hostap_hw.c, but they may have some
---
0.99.8.GIT


--- NEW FILE 0346-hostap-Fix-hostap_pci-build-with-PRISM2_IO_DEBUG.txt ---
Subject: [PATCH] hostap: Fix hostap_pci build with PRISM2_IO_DEBUG
From: Jouni Malinen <jkmaline at cc.hut.fi>
Date: 1128298739 -0700

The debug version of I/O functions in hostap_pci had not survived the
change to start using hw_priv pointer, so let's fix them to actually
define the local hw_priv variable.

Signed-off-by: Jouni Malinen <jkmaline at cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap_pci.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

applies-to: 11f1e2ec911c48a1e74563979457e8d299e414e5
f7a74447553d698795ba74b7e17e916000b0cb08
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 594cc29..0d7305d 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -59,11 +59,13 @@ static struct pci_device_id prism2_pci_i
 static inline void hfa384x_outb_debug(struct net_device *dev, int a, u8 v)
 {
 	struct hostap_interface *iface;
+	struct hostap_pci_priv *hw_priv;
 	local_info_t *local;
 	unsigned long flags;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
+	hw_priv = local->hw_priv;
 
 	spin_lock_irqsave(&local->lock, flags);
 	prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTB, a, v);
@@ -74,12 +76,14 @@ static inline void hfa384x_outb_debug(st
 static inline u8 hfa384x_inb_debug(struct net_device *dev, int a)
 {
 	struct hostap_interface *iface;
+	struct hostap_pci_priv *hw_priv;
 	local_info_t *local;
 	unsigned long flags;
 	u8 v;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
+	hw_priv = local->hw_priv;
 
 	spin_lock_irqsave(&local->lock, flags);
 	v = readb(hw_priv->mem_start + a);
@@ -91,11 +95,13 @@ static inline u8 hfa384x_inb_debug(struc
 static inline void hfa384x_outw_debug(struct net_device *dev, int a, u16 v)
 {
 	struct hostap_interface *iface;
+	struct hostap_pci_priv *hw_priv;
 	local_info_t *local;
 	unsigned long flags;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
+	hw_priv = local->hw_priv;
 
 	spin_lock_irqsave(&local->lock, flags);
 	prism2_io_debug_add(dev, PRISM2_IO_DEBUG_CMD_OUTW, a, v);
@@ -106,12 +112,14 @@ static inline void hfa384x_outw_debug(st
 static inline u16 hfa384x_inw_debug(struct net_device *dev, int a)
 {
 	struct hostap_interface *iface;
+	struct hostap_pci_priv *hw_priv;
 	local_info_t *local;
 	unsigned long flags;
 	u16 v;
 
 	iface = netdev_priv(dev);
 	local = iface->local;
+	hw_priv = local->hw_priv;
 
 	spin_lock_irqsave(&local->lock, flags);
 	v = readw(hw_priv->mem_start + a);
---
0.99.8.GIT


--- NEW FILE 0347-hostap-Do-not-free-local-hw_priv-before-unregistering-netdev.txt ---
Subject: [PATCH] hostap: Do not free local->hw_priv before unregistering netdev
From: Jouni Malinen <jkmaline at cc.hut.fi>
Date: 1128298740 -0700

local->hw_priv was being freed and set to NULL just before calling
prism2_free_local_data(). However, this may expose a race condition in
which something ends up trying to use hw_priv during shutdown. I
haven't noticed this happening, but better be safe than sorry, so
let's postpone hw_priv freeing to happen only after
prism2_free_local_data() has returned.

Signed-off-by: Jouni Malinen <jkmaline at cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap_cs.c  |    5 +++--
 drivers/net/wireless/hostap/hostap_pci.c |    9 ++-------
 drivers/net/wireless/hostap/hostap_plx.c |    7 ++-----
 3 files changed, 7 insertions(+), 14 deletions(-)

applies-to: 02143425097ceec545e4de3795a44e12531e8b78
c355184cd3cd58c9ffc78f2a17e0ac3563312ea7
diff --git a/drivers/net/wireless/hostap/hostap_cs.c b/drivers/net/wireless/hostap/hostap_cs.c
index 23bcc51..2643976 100644
--- a/drivers/net/wireless/hostap/hostap_cs.c
+++ b/drivers/net/wireless/hostap/hostap_cs.c
@@ -565,13 +565,14 @@ static void prism2_detach(dev_link_t *li
 	*linkp = link->next;
 	/* release net devices */
 	if (link->priv) {
+		struct hostap_cs_priv *hw_priv;
 		struct net_device *dev;
 		struct hostap_interface *iface;
 		dev = link->priv;
 		iface = netdev_priv(dev);
-		kfree(iface->local->hw_priv);
-		iface->local->hw_priv = NULL;
+		hw_priv = iface->local->hw_priv;
 		prism2_free_local_data(dev);
+		kfree(hw_priv);
 	}
 	kfree(link);
 }
diff --git a/drivers/net/wireless/hostap/hostap_pci.c b/drivers/net/wireless/hostap/hostap_pci.c
index 0d7305d..da0c80f 100644
--- a/drivers/net/wireless/hostap/hostap_pci.c
+++ b/drivers/net/wireless/hostap/hostap_pci.c
@@ -358,8 +358,6 @@ static int prism2_pci_probe(struct pci_d
 	return hostap_hw_ready(dev);
 
  fail:
-	kfree(hw_priv);
-
 	if (irq_registered && dev)
 		free_irq(dev->irq, dev);
 
@@ -370,10 +368,8 @@ static int prism2_pci_probe(struct pci_d
 
  err_out_disable:
 	pci_disable_device(pdev);
-	kfree(hw_priv);
-	if (local)
-		local->hw_priv = NULL;
 	prism2_free_local_data(dev);
+	kfree(hw_priv);
 
 	return -ENODEV;
 }
@@ -398,9 +394,8 @@ static void prism2_pci_remove(struct pci
 		free_irq(dev->irq, dev);
 
 	mem_start = hw_priv->mem_start;
-	kfree(hw_priv);
-	iface->local->hw_priv = NULL;
 	prism2_free_local_data(dev);
+	kfree(hw_priv);
 
 	iounmap(mem_start);
 
diff --git a/drivers/net/wireless/hostap/hostap_plx.c b/drivers/net/wireless/hostap/hostap_plx.c
index 85d3f8a..78d67b4 100644
--- a/drivers/net/wireless/hostap/hostap_plx.c
+++ b/drivers/net/wireless/hostap/hostap_plx.c
@@ -568,10 +568,8 @@ static int prism2_plx_probe(struct pci_d
 	return hostap_hw_ready(dev);
 
  fail:
-	kfree(hw_priv);
-	if (local)
-		local->hw_priv = NULL;
 	prism2_free_local_data(dev);
+	kfree(hw_priv);
 
 	if (irq_registered && dev)
 		free_irq(dev->irq, dev);
@@ -604,9 +602,8 @@ static void prism2_plx_remove(struct pci
 	if (dev->irq)
 		free_irq(dev->irq, dev);
 
-	kfree(iface->local->hw_priv);
-	iface->local->hw_priv = NULL;
 	prism2_free_local_data(dev);
+	kfree(hw_priv);
 	pci_disable_device(pdev);
 }
 
---
0.99.8.GIT


--- NEW FILE 0348-hostap-Unregister-netdevs-before-freeing-local-data.txt ---
Subject: [PATCH] hostap: Unregister netdevs before freeing local data
From: Jouni Malinen <jkmaline at cc.hut.fi>
Date: 1128298741 -0700

Unregister all netdevs before freeing local data. I was unable to
trigger any crashes without this change when running busy loops for
driver operations when ejecting a Prism2 PC Card. Anyway, should there
be a race condition with this, better make it less likely to happen by
unregistering the netdevs first.

Signed-off-by: Jouni Malinen <jkmaline at cc.hut.fi>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hostap/hostap_hw.c |   22 ++++++++++++----------
 1 files changed, 12 insertions(+), 10 deletions(-)

applies-to: f6de150b08f98540bf660cedffd77785ce75b479
7cb3cd090c2725b80561958a362c2ba15a7a8c86
diff --git a/drivers/net/wireless/hostap/hostap_hw.c b/drivers/net/wireless/hostap/hostap_hw.c
index e533a66..59fc155 100644
--- a/drivers/net/wireless/hostap/hostap_hw.c
+++ b/drivers/net/wireless/hostap/hostap_hw.c
@@ -3322,6 +3322,18 @@ static void prism2_free_local_data(struc
 	iface = netdev_priv(dev);
 	local = iface->local;
 
+	/* Unregister all netdevs before freeing local data. */
+	list_for_each_safe(ptr, n, &local->hostap_interfaces) {
+		iface = list_entry(ptr, struct hostap_interface, list);
+		if (iface->type == HOSTAP_INTERFACE_MASTER) {
+			/* special handling for this interface below */
+			continue;
+		}
+		hostap_remove_interface(iface->dev, 0, 1);
+	}
+
+	unregister_netdev(local->dev);
+
 	flush_scheduled_work();
 
 	if (timer_pending(&local->crypt_deinit_timer))
@@ -3382,15 +3394,6 @@ static void prism2_free_local_data(struc
 	prism2_download_free_data(local->dl_sec);
 #endif /* PRISM2_DOWNLOAD_SUPPORT */
 
-	list_for_each_safe(ptr, n, &local->hostap_interfaces) {
-		iface = list_entry(ptr, struct hostap_interface, list);
-		if (iface->type == HOSTAP_INTERFACE_MASTER) {
-			/* special handling for this interface below */
-			continue;
-		}
-		hostap_remove_interface(iface->dev, 0, 1);
-	}
-
 	prism2_clear_set_tim_queue(local);
 
 	list_for_each_safe(ptr, n, &local->bss_list) {
@@ -3403,7 +3406,6 @@ static void prism2_free_local_data(struc
 	kfree(local->last_scan_results);
 	kfree(local->generic_elem);
 
-	unregister_netdev(local->dev);
 	free_netdev(local->dev);
 }
 
---
0.99.8.GIT


--- NEW FILE 0355-S2io-MSI-MSI-X-support-runtime-configurable.txt ---
Subject: [PATCH] S2io: MSI/MSI-X support (runtime configurable)
From: Ravinandan Arakali <ravinandan.arakali at neterion.com>
Date: 1128422484 -0400

This patch adds support for MSI/MSI-X feature to the driver.  It is
a runtime parameter(for now, loadable parameter).  Default is INTA.

Patch has been tested on IA64 platform with Xframe II adapter,
both of which support MSI-X feature.  An improvement of about 7%
in throughput(both Tx and Rx) was observed and a reduction by 7%
in CPU utilization during Tx test.

Signed-off-by: Ravinandan Arakali <ravinandan.arakali at neterion.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/s2io.c |  543 +++++++++++++++++++++++++++++++++++++++++++++++++---
 drivers/net/s2io.h |   50 ++++-
 2 files changed, 556 insertions(+), 37 deletions(-)

applies-to: d356eab72377f2576ad356de66daec23f28529a5
cc6e7c44f4b8ab13acf5521cd4b312848122179f
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index dd451e0..4b9f182 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -67,7 +67,7 @@
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
-static char s2io_driver_version[] = "Version 2.0.8.1";
+static char s2io_driver_version[] = "Version 2.0.9.1";
 
 static inline int RXD_IS_UP2DT(RxD_t *rxdp)
 {
@@ -307,6 +307,8 @@ static unsigned int indicate_max_pkts;
 #endif
 /* Frequency of Rx desc syncs expressed as power of 2 */
 static unsigned int rxsync_frequency = 3;
+/* Interrupt type. Values can be 0(INTA), 1(MSI), 2(MSI_X) */
+static unsigned int intr_type = 0;
 
 /*
  * S2IO device table.
@@ -1396,8 +1398,13 @@ static int init_nic(struct s2io_nic *nic
 		writeq(val64, &bar0->rti_data1_mem);
 
 		val64 = RTI_DATA2_MEM_RX_UFC_A(0x1) |
-		    RTI_DATA2_MEM_RX_UFC_B(0x2) |
-		    RTI_DATA2_MEM_RX_UFC_C(0x40) | RTI_DATA2_MEM_RX_UFC_D(0x80);
+		    RTI_DATA2_MEM_RX_UFC_B(0x2) ;
+		if (nic->intr_type == MSI_X)
+		    val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x20) | \
+				RTI_DATA2_MEM_RX_UFC_D(0x40));
+		else
+		    val64 |= (RTI_DATA2_MEM_RX_UFC_C(0x40) | \
+				RTI_DATA2_MEM_RX_UFC_D(0x80));
 		writeq(val64, &bar0->rti_data2_mem);
 
 		for (i = 0; i < config->rx_ring_num; i++) {
@@ -1507,17 +1514,15 @@ static int init_nic(struct s2io_nic *nic
 #define LINK_UP_DOWN_INTERRUPT		1
 #define MAC_RMAC_ERR_TIMER		2
 
-#if defined(CONFIG_MSI_MODE) || defined(CONFIG_MSIX_MODE)
-#define s2io_link_fault_indication(x) MAC_RMAC_ERR_TIMER
-#else
 int s2io_link_fault_indication(nic_t *nic)
 {
+	if (nic->intr_type != INTA)
+		return MAC_RMAC_ERR_TIMER;
 	if (nic->device_type == XFRAME_II_DEVICE)
 		return LINK_UP_DOWN_INTERRUPT;
 	else
 		return MAC_RMAC_ERR_TIMER;
 }
-#endif
 
 /**
  *  en_dis_able_nic_intrs - Enable or Disable the interrupts
@@ -1941,11 +1946,14 @@ static int start_nic(struct s2io_nic *ni
 	}
 
 	/*  Enable select interrupts */
-	interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
-	interruptible |= TX_PIC_INTR | RX_PIC_INTR;
-	interruptible |= TX_MAC_INTR | RX_MAC_INTR;
-
-	en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);
+	if (nic->intr_type != INTA)
+		en_dis_able_nic_intrs(nic, ENA_ALL_INTRS, DISABLE_INTRS);
+	else {
+		interruptible = TX_TRAFFIC_INTR | RX_TRAFFIC_INTR;
+		interruptible |= TX_PIC_INTR | RX_PIC_INTR;
+		interruptible |= TX_MAC_INTR | RX_MAC_INTR;
+		en_dis_able_nic_intrs(nic, interruptible, ENABLE_INTRS);
+	}
 
 	/*
 	 * With some switches, link might be already up at this point.
@@ -2633,11 +2641,11 @@ static void tx_intr_handler(fifo_info_t 
 			err = txdlp->Control_1 & TXD_T_CODE;
 			if ((err >> 48) == 0xA) {
 				DBG_PRINT(TX_DBG, "TxD returned due \
-						to loss of link\n");
+to loss of link\n");
 			}
 			else {
 				DBG_PRINT(ERR_DBG, "***TxD error \
-						%llx\n", err);
+%llx\n", err);
 			}
 		}
 
@@ -2854,6 +2862,9 @@ void s2io_reset(nic_t * sp)
 	/* Set swapper to enable I/O register access */
 	s2io_set_swapper(sp);
 
+	/* Restore the MSIX table entries from local variables */
+	restore_xmsi_data(sp);
+
 	/* Clear certain PCI/PCI-X fields after reset */
 	if (sp->device_type == XFRAME_II_DEVICE) {
 		/* Clear parity err detect bit */
@@ -2983,8 +2994,9 @@ int s2io_set_swapper(nic_t * sp)
 		 SWAPPER_CTRL_RXD_W_FE |
 		 SWAPPER_CTRL_RXF_W_FE |
 		 SWAPPER_CTRL_XMSI_FE |
-		 SWAPPER_CTRL_XMSI_SE |
 		 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
+	if (nic->intr_type == INTA)
+		val64 |= SWAPPER_CTRL_XMSI_SE;
 	writeq(val64, &bar0->swapper_ctrl);
 #else
 	/*
@@ -3005,8 +3017,9 @@ int s2io_set_swapper(nic_t * sp)
 		 SWAPPER_CTRL_RXD_W_SE |
 		 SWAPPER_CTRL_RXF_W_FE |
 		 SWAPPER_CTRL_XMSI_FE |
-		 SWAPPER_CTRL_XMSI_SE |
 		 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
+	if (sp->intr_type == INTA)
+		val64 |= SWAPPER_CTRL_XMSI_SE;
 	writeq(val64, &bar0->swapper_ctrl);
 #endif
 	val64 = readq(&bar0->swapper_ctrl);
@@ -3028,6 +3041,201 @@ int s2io_set_swapper(nic_t * sp)
 	return SUCCESS;
 }
 
+int wait_for_msix_trans(nic_t *nic, int i)
+{
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	u64 val64;
+	int ret = 0, cnt = 0;
+
+	do {
+		val64 = readq(&bar0->xmsi_access);
+		if (!(val64 & BIT(15)))
+			break;
+		mdelay(1);
+		cnt++;
+	} while(cnt < 5);
+	if (cnt == 5) {
+		DBG_PRINT(ERR_DBG, "XMSI # %d Access failed\n", i);
+		ret = 1;
+	}
+
+	return ret;
+}
+
+void restore_xmsi_data(nic_t *nic)
+{
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	u64 val64;
+	int i;
+
+	for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
+		writeq(nic->msix_info[i].addr, &bar0->xmsi_address);
+		writeq(nic->msix_info[i].data, &bar0->xmsi_data);
+		val64 = (BIT(7) | BIT(15) | vBIT(i, 26, 6));
+		writeq(val64, &bar0->xmsi_access);
+		if (wait_for_msix_trans(nic, i)) {
+			DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+			continue;
+		}
+	}
+}
+
+void store_xmsi_data(nic_t *nic)
+{
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	u64 val64, addr, data;
+	int i;
+
+	/* Store and display */
+	for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
+		val64 = (BIT(15) | vBIT(i, 26, 6));
+		writeq(val64, &bar0->xmsi_access);
+		if (wait_for_msix_trans(nic, i)) {
+			DBG_PRINT(ERR_DBG, "failed in %s\n", __FUNCTION__);
+			continue;
+		}
+		addr = readq(&bar0->xmsi_address);
+		data = readq(&bar0->xmsi_data);
+		if (addr && data) {
+			nic->msix_info[i].addr = addr;
+			nic->msix_info[i].data = data;
+		}
+	}
+}
+
+int s2io_enable_msi(nic_t *nic)
+{
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	u16 msi_ctrl, msg_val;
+	struct config_param *config = &nic->config;
+	struct net_device *dev = nic->dev;
+	u64 val64, tx_mat, rx_mat;
+	int i, err;
+
+	val64 = readq(&bar0->pic_control);
+	val64 &= ~BIT(1);
+	writeq(val64, &bar0->pic_control);
+
+	err = pci_enable_msi(nic->pdev);
+	if (err) {
+		DBG_PRINT(ERR_DBG, "%s: enabling MSI failed\n",
+			  nic->dev->name);
+		return err;
+	}
+
+	/*
+	 * Enable MSI and use MSI-1 in stead of the standard MSI-0
+	 * for interrupt handling.
+	 */
+	pci_read_config_word(nic->pdev, 0x4c, &msg_val);
+	msg_val ^= 0x1;
+	pci_write_config_word(nic->pdev, 0x4c, msg_val);
+	pci_read_config_word(nic->pdev, 0x4c, &msg_val);
+
+	pci_read_config_word(nic->pdev, 0x42, &msi_ctrl);
+	msi_ctrl |= 0x10;
+	pci_write_config_word(nic->pdev, 0x42, msi_ctrl);
+
+	/* program MSI-1 into all usable Tx_Mat and Rx_Mat fields */
+	tx_mat = readq(&bar0->tx_mat0_n[0]);
+	for (i=0; i<config->tx_fifo_num; i++) {
+		tx_mat |= TX_MAT_SET(i, 1);
+	}
+	writeq(tx_mat, &bar0->tx_mat0_n[0]);
+
+	rx_mat = readq(&bar0->rx_mat);
+	for (i=0; i<config->rx_ring_num; i++) {
+		rx_mat |= RX_MAT_SET(i, 1);
+	}
+	writeq(rx_mat, &bar0->rx_mat);
+
+	dev->irq = nic->pdev->irq;
+	return 0;
+}
+
+int s2io_enable_msi_x(nic_t *nic)
+{
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	u64 tx_mat, rx_mat;
+	u16 msi_control; /* Temp variable */
+	int ret, i, j, msix_indx = 1;
+
+	nic->entries = kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct msix_entry),
+			       GFP_KERNEL);
+	if (nic->entries == NULL) {
+		DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+		return -ENOMEM;
+	}
+	memset(nic->entries, 0, MAX_REQUESTED_MSI_X * sizeof(struct msix_entry));
+
+	nic->s2io_entries =
+		kmalloc(MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry),
+				   GFP_KERNEL);
+	if (nic->s2io_entries == NULL) {
+		DBG_PRINT(ERR_DBG, "%s: Memory allocation failed\n", __FUNCTION__);
+		kfree(nic->entries);
+		return -ENOMEM;
+	}
+	memset(nic->s2io_entries, 0,
+	       MAX_REQUESTED_MSI_X * sizeof(struct s2io_msix_entry));
+
+	for (i=0; i< MAX_REQUESTED_MSI_X; i++) {
+		nic->entries[i].entry = i;
+		nic->s2io_entries[i].entry = i;
+		nic->s2io_entries[i].arg = NULL;
+		nic->s2io_entries[i].in_use = 0;
+	}
+
+	tx_mat = readq(&bar0->tx_mat0_n[0]);
+	for (i=0; i<nic->config.tx_fifo_num; i++, msix_indx++) {
+		tx_mat |= TX_MAT_SET(i, msix_indx);
+		nic->s2io_entries[msix_indx].arg = &nic->mac_control.fifos[i];
+		nic->s2io_entries[msix_indx].type = MSIX_FIFO_TYPE;
+		nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
+	}
+	writeq(tx_mat, &bar0->tx_mat0_n[0]);
+
+	if (!nic->config.bimodal) {
+		rx_mat = readq(&bar0->rx_mat);
+		for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
+			rx_mat |= RX_MAT_SET(j, msix_indx);
+			nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+			nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
+			nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
+		}
+		writeq(rx_mat, &bar0->rx_mat);
+	} else {
+		tx_mat = readq(&bar0->tx_mat0_n[7]);
+		for (j=0; j<nic->config.rx_ring_num; j++, msix_indx++) {
+			tx_mat |= TX_MAT_SET(i, msix_indx);
+			nic->s2io_entries[msix_indx].arg = &nic->mac_control.rings[j];
+			nic->s2io_entries[msix_indx].type = MSIX_RING_TYPE;
+			nic->s2io_entries[msix_indx].in_use = MSIX_FLG;
+		}
+		writeq(tx_mat, &bar0->tx_mat0_n[7]);
+	}
+
+	ret = pci_enable_msix(nic->pdev, nic->entries, MAX_REQUESTED_MSI_X);
+	if (ret) {
+		DBG_PRINT(ERR_DBG, "%s: Enabling MSIX failed\n", nic->dev->name);
+		kfree(nic->entries);
+		kfree(nic->s2io_entries);
+		nic->entries = NULL;
+		nic->s2io_entries = NULL;
+		return -ENOMEM;
+	}
+
+	/*
+	 * To enable MSI-X, MSI also needs to be enabled, due to a bug
+	 * in the herc NIC. (Temp change, needs to be removed later)
+	 */
+	pci_read_config_word(nic->pdev, 0x42, &msi_control);
+	msi_control |= 0x1; /* Enable MSI */
+	pci_write_config_word(nic->pdev, 0x42, msi_control);
+
+	return 0;
+}
+
 /* ********************************************************* *
  * Functions defined below concern the OS part of the driver *
  * ********************************************************* */
@@ -3048,6 +3256,8 @@ int s2io_open(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
 	int err = 0;
+	int i;
+	u16 msi_control; /* Temp variable */
 
 	/*
 	 * Make sure you have link off by default every time
@@ -3064,13 +3274,55 @@ int s2io_open(struct net_device *dev)
 		goto hw_init_failed;
 	}
 
+	/* Store the values of the MSIX table in the nic_t structure */
+	store_xmsi_data(sp);
+
 	/* After proper initialization of H/W, register ISR */
-	err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ,
-			  sp->name, dev);
-	if (err) {
-		DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
-			  dev->name);
-		goto isr_registration_failed;
+	if (sp->intr_type == MSI) {
+		err = request_irq((int) sp->pdev->irq, s2io_msi_handle, 
+			SA_SHIRQ, sp->name, dev);
+		if (err) {
+			DBG_PRINT(ERR_DBG, "%s: MSI registration \
+failed\n", dev->name);
+			goto isr_registration_failed;
+		}
+	}
+	if (sp->intr_type == MSI_X) {
+		for (i=1; (sp->s2io_entries[i].in_use == MSIX_FLG); i++) {
+			if (sp->s2io_entries[i].type == MSIX_FIFO_TYPE) {
+				sprintf(sp->desc1, "%s:MSI-X-%d-TX",
+					dev->name, i);
+				err = request_irq(sp->entries[i].vector,
+					  s2io_msix_fifo_handle, 0, sp->desc1,
+					  sp->s2io_entries[i].arg);
+				DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc1, 
+							sp->msix_info[i].addr);
+			} else {
+				sprintf(sp->desc2, "%s:MSI-X-%d-RX",
+					dev->name, i);
+				err = request_irq(sp->entries[i].vector,
+					  s2io_msix_ring_handle, 0, sp->desc2,
+					  sp->s2io_entries[i].arg);
+				DBG_PRINT(ERR_DBG, "%s @ 0x%llx\n", sp->desc2, 
+							sp->msix_info[i].addr);
+			}
+			if (err) {
+				DBG_PRINT(ERR_DBG, "%s: MSI-X-%d registration \
+failed\n", dev->name, i);
+				DBG_PRINT(ERR_DBG, "Returned: %d\n", err);
+				goto isr_registration_failed;
+			}
+			sp->s2io_entries[i].in_use = MSIX_REGISTERED_SUCCESS;
+		}
+	}
+	if (sp->intr_type == INTA) {
+		err = request_irq((int) sp->pdev->irq, s2io_isr, SA_SHIRQ,
+				sp->name, dev);
+		if (err) {
+			DBG_PRINT(ERR_DBG, "%s: ISR registration failed\n",
+				  dev->name);
+			goto isr_registration_failed;
+		}
 	}
 
 	if (s2io_set_mac_addr(dev, dev->dev_addr) == FAILURE) {
@@ -3083,11 +3335,37 @@ int s2io_open(struct net_device *dev)
 	return 0;
 
 setting_mac_address_failed:
-	free_irq(sp->pdev->irq, dev);
+	if (sp->intr_type != MSI_X)
+		free_irq(sp->pdev->irq, dev);
 isr_registration_failed:
 	del_timer_sync(&sp->alarm_timer);
+	if (sp->intr_type == MSI_X) {
+		if (sp->device_type == XFRAME_II_DEVICE) {
+			for (i=1; (sp->s2io_entries[i].in_use == 
+				MSIX_REGISTERED_SUCCESS); i++) {
+				int vector = sp->entries[i].vector;
+				void *arg = sp->s2io_entries[i].arg;
+
+				free_irq(vector, arg);
+			}
+			pci_disable_msix(sp->pdev);
+
+			/* Temp */
+			pci_read_config_word(sp->pdev, 0x42, &msi_control);
+			msi_control &= 0xFFFE; /* Disable MSI */
+			pci_write_config_word(sp->pdev, 0x42, msi_control);
+		}
+	}
+	else if (sp->intr_type == MSI)
+		pci_disable_msi(sp->pdev);
 	s2io_reset(sp);
 hw_init_failed:
+	if (sp->intr_type == MSI_X) {
+		if (sp->entries)
+			kfree(sp->entries);
+		if (sp->s2io_entries)
+			kfree(sp->s2io_entries);
+	}
 	return err;
 }
 
@@ -3107,12 +3385,35 @@ hw_init_failed:
 int s2io_close(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
+	int i;
+	u16 msi_control;
+
 	flush_scheduled_work();
 	netif_stop_queue(dev);
 	/* Reset card, kill tasklet and free Tx and Rx buffers. */
 	s2io_card_down(sp);
 
-	free_irq(sp->pdev->irq, dev);
+	if (sp->intr_type == MSI_X) {
+		if (sp->device_type == XFRAME_II_DEVICE) {
+			for (i=1; (sp->s2io_entries[i].in_use == 
+					MSIX_REGISTERED_SUCCESS); i++) {
+				int vector = sp->entries[i].vector;
+				void *arg = sp->s2io_entries[i].arg;
+
+				free_irq(vector, arg);
+			}
+			pci_read_config_word(sp->pdev, 0x42, &msi_control);
+			msi_control &= 0xFFFE; /* Disable MSI */
+			pci_write_config_word(sp->pdev, 0x42, msi_control);
+
+			pci_disable_msix(sp->pdev);
+		}
+	}
+	else {
+		free_irq(sp->pdev->irq, dev);
+		if (sp->intr_type == MSI)
+			pci_disable_msi(sp->pdev);
+	}	
 	sp->device_close_flag = TRUE;	/* Device is shut down. */
 	return 0;
 }
@@ -3278,6 +3579,104 @@ s2io_alarm_handle(unsigned long data)
 	mod_timer(&sp->alarm_timer, jiffies + HZ / 2);
 }
 
+static irqreturn_t
+s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+	struct net_device *dev = (struct net_device *) dev_id;
+	nic_t *sp = dev->priv;
+	int i;
+	int ret;
+	mac_info_t *mac_control;
+	struct config_param *config;
+
+	atomic_inc(&sp->isr_cnt);
+	mac_control = &sp->mac_control;
+	config = &sp->config;
+	DBG_PRINT(INTR_DBG, "%s: MSI handler\n", __FUNCTION__);
+
+	/* If Intr is because of Rx Traffic */
+	for (i = 0; i < config->rx_ring_num; i++)
+		rx_intr_handler(&mac_control->rings[i]);
+
+	/* If Intr is because of Tx Traffic */
+	for (i = 0; i < config->tx_fifo_num; i++)
+		tx_intr_handler(&mac_control->fifos[i]);
+
+	/*
+	 * If the Rx buffer count is below the panic threshold then
+	 * reallocate the buffers from the interrupt handler itself,
+	 * else schedule a tasklet to reallocate the buffers.
+	 */
+	for (i = 0; i < config->rx_ring_num; i++) {
+		int rxb_size = atomic_read(&sp->rx_bufs_left[i]);
+		int level = rx_buffer_level(sp, rxb_size, i);
+
+		if ((level == PANIC) && (!TASKLET_IN_USE)) {
+			DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", dev->name);
+			DBG_PRINT(INTR_DBG, "PANIC levels\n");
+			if ((ret = fill_rx_buffers(sp, i)) == -ENOMEM) {
+				DBG_PRINT(ERR_DBG, "%s:Out of memory",
+					  dev->name);
+				DBG_PRINT(ERR_DBG, " in ISR!!\n");
+				clear_bit(0, (&sp->tasklet_status));
+				atomic_dec(&sp->isr_cnt);
+				return IRQ_HANDLED;
+			}
+			clear_bit(0, (&sp->tasklet_status));
+		} else if (level == LOW) {
+			tasklet_schedule(&sp->task);
+		}
+	}
+
+	atomic_dec(&sp->isr_cnt);
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+	ring_info_t *ring = (ring_info_t *)dev_id;
+	nic_t *sp = ring->nic;
+	int rxb_size, level, rng_n;
+
+	atomic_inc(&sp->isr_cnt);
+	rx_intr_handler(ring);
+
+	rng_n = ring->ring_no;
+	rxb_size = atomic_read(&sp->rx_bufs_left[rng_n]);
+	level = rx_buffer_level(sp, rxb_size, rng_n);
+
+	if ((level == PANIC) && (!TASKLET_IN_USE)) {
+		int ret;
+		DBG_PRINT(INTR_DBG, "%s: Rx BD hit ", __FUNCTION__);
+		DBG_PRINT(INTR_DBG, "PANIC levels\n");
+		if ((ret = fill_rx_buffers(sp, rng_n)) == -ENOMEM) {
+			DBG_PRINT(ERR_DBG, "Out of memory in %s",
+				  __FUNCTION__);
+			clear_bit(0, (&sp->tasklet_status));
+			return IRQ_HANDLED;
+		}
+		clear_bit(0, (&sp->tasklet_status));
+	} else if (level == LOW) {
+		tasklet_schedule(&sp->task);
+	}
+	atomic_dec(&sp->isr_cnt);
+
+	return IRQ_HANDLED;
+}
+
+static irqreturn_t
+s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs)
+{
+	fifo_info_t *fifo = (fifo_info_t *)dev_id;
+	nic_t *sp = fifo->nic;
+
+	atomic_inc(&sp->isr_cnt);
+	tx_intr_handler(fifo);
+	atomic_dec(&sp->isr_cnt);
+	return IRQ_HANDLED;
+}
+
 static void s2io_txpic_intr_handle(nic_t *sp)
 {
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
@@ -4932,7 +5331,7 @@ static void s2io_card_down(nic_t * sp)
 
 static int s2io_card_up(nic_t * sp)
 {
-	int i, ret;
+	int i, ret = 0;
 	mac_info_t *mac_control;
 	struct config_param *config;
 	struct net_device *dev = (struct net_device *) sp->dev;
@@ -4944,6 +5343,15 @@ static int s2io_card_up(nic_t * sp)
 		return -ENODEV;
 	}
 
+	if (sp->intr_type == MSI)
+		ret = s2io_enable_msi(sp);
+	else if (sp->intr_type == MSI_X)
+		ret = s2io_enable_msi_x(sp);
+	if (ret) {
+		DBG_PRINT(ERR_DBG, "%s: Defaulting to INTA\n", dev->name);
+		sp->intr_type = INTA;
+	}
+
 	/*
 	 * Initializing the Rx buffers. For now we are considering only 1
 	 * Rx ring and initializing buffers into 30 Rx blocks
@@ -5245,6 +5653,7 @@ module_param(bimodal, bool, 0);
 module_param(indicate_max_pkts, int, 0);
 #endif
 module_param(rxsync_frequency, int, 0);
+module_param(intr_type, int, 0);
 
 /**
  *  s2io_init_nic - Initialization of the adapter .
@@ -5274,9 +5683,16 @@ s2io_init_nic(struct pci_dev *pdev, cons
 	mac_info_t *mac_control;
 	struct config_param *config;
 	int mode;
+	u8 dev_intr_type = intr_type;
 
 #ifdef CONFIG_S2IO_NAPI
-	DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n");
+	if (dev_intr_type != INTA) {
+		DBG_PRINT(ERR_DBG, "NAPI cannot be enabled when MSI/MSI-X \
+is enabled. Defaulting to INTA\n");
+		dev_intr_type = INTA;
+	}
+	else
+		DBG_PRINT(ERR_DBG, "NAPI support has been enabled\n");
 #endif
 
 	if ((ret = pci_enable_device(pdev))) {
@@ -5303,10 +5719,35 @@ s2io_init_nic(struct pci_dev *pdev, cons
 		return -ENOMEM;
 	}
 
-	if (pci_request_regions(pdev, s2io_driver_name)) {
-		DBG_PRINT(ERR_DBG, "Request Regions failed\n"),
-		    pci_disable_device(pdev);
-		return -ENODEV;
+	if ((dev_intr_type == MSI_X) && 
+			((pdev->device != PCI_DEVICE_ID_HERC_WIN) &&
+			(pdev->device != PCI_DEVICE_ID_HERC_UNI))) {
+		DBG_PRINT(ERR_DBG, "Xframe I does not support MSI_X. \
+Defaulting to INTA\n");
+		dev_intr_type = INTA;
+	}
+	if (dev_intr_type != MSI_X) {
+		if (pci_request_regions(pdev, s2io_driver_name)) {
+			DBG_PRINT(ERR_DBG, "Request Regions failed\n"),
+			    pci_disable_device(pdev);
+			return -ENODEV;
+		}
+	}
+	else {
+		if (!(request_mem_region(pci_resource_start(pdev, 0),
+               	         pci_resource_len(pdev, 0), s2io_driver_name))) {
+			DBG_PRINT(ERR_DBG, "bar0 Request Regions failed\n");
+			pci_disable_device(pdev);
+			return -ENODEV;
+		}
+        	if (!(request_mem_region(pci_resource_start(pdev, 2),
+               	         pci_resource_len(pdev, 2), s2io_driver_name))) {
+			DBG_PRINT(ERR_DBG, "bar1 Request Regions failed\n");
+                	release_mem_region(pci_resource_start(pdev, 0),
+                                   pci_resource_len(pdev, 0));
+			pci_disable_device(pdev);
+			return -ENODEV;
+		}
 	}
 
 	dev = alloc_etherdev(sizeof(nic_t));
@@ -5329,6 +5770,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
 	sp->pdev = pdev;
 	sp->high_dma_flag = dma_flag;
 	sp->device_enabled_once = FALSE;
+	sp->intr_type = dev_intr_type;
 
 	if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
 		(pdev->device == PCI_DEVICE_ID_HERC_UNI))
@@ -5336,6 +5778,7 @@ s2io_init_nic(struct pci_dev *pdev, cons
 	else
 		sp->device_type = XFRAME_I_DEVICE;
 
+		
 	/* Initialize some PCI/PCI-X fields of the NIC. */
 	s2io_init_pci(sp);
 
@@ -5577,6 +6020,17 @@ s2io_init_nic(struct pci_dev *pdev, cons
 #ifdef CONFIG_2BUFF_MODE
 		DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
 #endif
+		switch(sp->intr_type) {
+			case INTA:
+				DBG_PRINT(ERR_DBG, ", Intr type INTA");
+				break;
+			case MSI:
+				DBG_PRINT(ERR_DBG, ", Intr type MSI");
+				break;
+			case MSI_X:
+				DBG_PRINT(ERR_DBG, ", Intr type MSI-X");
+				break;
+		}
 
 		DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n");
 		DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
@@ -5601,6 +6055,17 @@ s2io_init_nic(struct pci_dev *pdev, cons
 #ifdef CONFIG_2BUFF_MODE
 		DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
 #endif
+		switch(sp->intr_type) {
+			case INTA:
+				DBG_PRINT(ERR_DBG, ", Intr type INTA");
+				break;
+			case MSI:
+				DBG_PRINT(ERR_DBG, ", Intr type MSI");
+				break;
+			case MSI_X:
+				DBG_PRINT(ERR_DBG, ", Intr type MSI-X");
+				break;
+		}
 		DBG_PRINT(ERR_DBG, "\nCopyright(c) 2002-2005 Neterion Inc.\n");
 		DBG_PRINT(ERR_DBG, "MAC ADDR: %02x:%02x:%02x:%02x:%02x:%02x\n",
 			  sp->def_mac_addr[0].mac_addr[0],
@@ -5644,7 +6109,14 @@ s2io_init_nic(struct pci_dev *pdev, cons
       mem_alloc_failed:
 	free_shared_mem(sp);
 	pci_disable_device(pdev);
-	pci_release_regions(pdev);
+	if (dev_intr_type != MSI_X)
+		pci_release_regions(pdev);
+	else {
+		release_mem_region(pci_resource_start(pdev, 0),
+			pci_resource_len(pdev, 0));
+		release_mem_region(pci_resource_start(pdev, 2),
+			pci_resource_len(pdev, 2));
+	}
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(dev);
 
@@ -5678,7 +6150,14 @@ static void __devexit s2io_rem_nic(struc
 	iounmap(sp->bar0);
 	iounmap(sp->bar1);
 	pci_disable_device(pdev);
-	pci_release_regions(pdev);
+	if (sp->intr_type != MSI_X)
+		pci_release_regions(pdev);
+	else {
+		release_mem_region(pci_resource_start(pdev, 0),
+			pci_resource_len(pdev, 0));
+		release_mem_region(pci_resource_start(pdev, 2),
+			pci_resource_len(pdev, 2));
+	}
 	pci_set_drvdata(pdev, NULL);
 	free_netdev(dev);
 }
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 89151cb..1cc24b5 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -652,6 +652,30 @@ typedef struct {
 #define SMALL_BLK_CNT	30
 #define LARGE_BLK_CNT	100
 
+/*
+ * Structure to keep track of the MSI-X vectors and the corresponding
+ * argument registered against each vector
+ */
+#define MAX_REQUESTED_MSI_X	17
+struct s2io_msix_entry
+{
+	u16 vector;
+	u16 entry;
+	void *arg;
+
+	u8 type;
+#define	MSIX_FIFO_TYPE	1
+#define	MSIX_RING_TYPE	2
+
+	u8 in_use;
+#define MSIX_REGISTERED_SUCCESS	0xAA
+};
+
+struct msix_info_st {
+	u64 addr;
+	u64 data;
+};
+
 /* Structure representing one instance of the NIC */
 struct s2io_nic {
 #ifdef CONFIG_S2IO_NAPI
@@ -719,13 +743,8 @@ struct s2io_nic {
 	 *  a schedule task that will set the correct Link state once the
 	 *  NIC's PHY has stabilized after a state change.
 	 */
-#ifdef INIT_TQUEUE
-	struct tq_struct rst_timer_task;
-	struct tq_struct set_link_task;
-#else
 	struct work_struct rst_timer_task;
 	struct work_struct set_link_task;
-#endif
 
 	/* Flag that can be used to turn on or turn off the Rx checksum
 	 * offload feature.
@@ -748,10 +767,23 @@ struct s2io_nic {
 	atomic_t card_state;
 	volatile unsigned long link_state;
 	struct vlan_group *vlgrp;
+#define MSIX_FLG                0xA5
+	struct msix_entry *entries;
+	struct s2io_msix_entry *s2io_entries;
+	char desc1[35];
+	char desc2[35];
+
+	struct msix_info_st msix_info[0x3f];
+
 #define XFRAME_I_DEVICE		1
 #define XFRAME_II_DEVICE	2
 	u8 device_type;
 
+#define INTA	0
+#define MSI	1
+#define MSI_X	2
+	u8 intr_type;
+
 	spinlock_t	rx_lock;
 	atomic_t	isr_cnt;
 };
@@ -886,6 +918,13 @@ static int s2io_poll(struct net_device *
 static void s2io_init_pci(nic_t * sp);
 int s2io_set_mac_addr(struct net_device *dev, u8 * addr);
 static void s2io_alarm_handle(unsigned long data);
+static int s2io_enable_msi(nic_t *nic);
+static irqreturn_t s2io_msi_handle(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t
+s2io_msix_ring_handle(int irq, void *dev_id, struct pt_regs *regs);
+static irqreturn_t
+s2io_msix_fifo_handle(int irq, void *dev_id, struct pt_regs *regs);
+int s2io_enable_msi_x(nic_t *nic);
 static irqreturn_t s2io_isr(int irq, void *dev_id, struct pt_regs *regs);
 static int verify_xena_quiescence(nic_t *sp, u64 val64, int flag);
 static struct ethtool_ops netdev_ethtool_ops;
@@ -894,4 +933,5 @@ int s2io_set_swapper(nic_t * sp);
 static void s2io_card_down(nic_t *nic);
 static int s2io_card_up(nic_t *nic);
 int get_xena_rev_id(struct pci_dev *pdev);
+void restore_xmsi_data(nic_t *nic);
 #endif				/* _S2IO_H */
---
0.99.8.GIT


--- NEW FILE 0356-e1000-Support-for-82571-and-82572-controllers.txt ---
Subject: [PATCH] e1000: Support for 82571 and 82572 controllers
From: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Date: 1128423539 -0400

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan at intel.com>
Signed-off-by: John Ronciak <john.ronciak at intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_ethtool.c |    9 +-
 drivers/net/e1000/e1000_hw.c      |  219 +++++++++++++++++++++++++++++++------
 drivers/net/e1000/e1000_hw.h      |   96 ++++++++++++++--
 drivers/net/e1000/e1000_main.c    |  102 ++++++++++++++++-
 4 files changed, 372 insertions(+), 54 deletions(-)

applies-to: 9a95e57befa59f6a50e5eb8ef4c9f8ae26816b87
868d5309942927dc86f57009420c5d366ec05daa
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 8f3a134..5f9a36b 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -696,6 +696,11 @@ e1000_reg_test(struct e1000_adapter *ada
 	 * Some bits that get toggled are ignored.
 	 */
         switch (adapter->hw.mac_type) {
+	/* there are several bits on newer hardware that are r/w */
+	case e1000_82571:
+	case e1000_82572:
+		toggle = 0x7FFFF3FF;
+		break;
 	case e1000_82573:
 		toggle = 0x7FFFF033;
 		break;
@@ -1245,6 +1250,8 @@ e1000_set_phy_loopback(struct e1000_adap
 	case e1000_82541_rev_2:
 	case e1000_82547:
 	case e1000_82547_rev_2:
+	case e1000_82571:
+	case e1000_82572:
 	case e1000_82573:
 		return e1000_integrated_phy_loopback(adapter);
 		break;
@@ -1625,7 +1632,7 @@ e1000_phys_id(struct net_device *netdev,
 	if(!data || data > (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ))
 		data = (uint32_t)(MAX_SCHEDULE_TIMEOUT / HZ);
 
-	if(adapter->hw.mac_type < e1000_82573) {
+	if(adapter->hw.mac_type < e1000_82571) {
 		if(!adapter->blink_timer.function) {
 			init_timer(&adapter->blink_timer);
 			adapter->blink_timer.function = e1000_led_blink_callback;
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 045f542..7d627dd 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -83,14 +83,14 @@ uint16_t e1000_igp_cable_length_table[IG
 
 static const
 uint16_t e1000_igp_2_cable_length_table[IGP02E1000_AGC_LENGTH_TABLE_SIZE] =
-    { 8, 13, 17, 19, 21, 23, 25, 27, 29, 31, 33, 35, 37, 39, 41, 43,
-      22, 24, 27, 30, 32, 35, 37, 40, 42, 44, 47, 49, 51, 54, 56, 58,
-      32, 35, 38, 41, 44, 47, 50, 53, 55, 58, 61, 63, 66, 69, 71, 74,
-      43, 47, 51, 54, 58, 61, 64, 67, 71, 74, 77, 80, 82, 85, 88, 90,
-      57, 62, 66, 70, 74, 77, 81, 85, 88, 91, 94, 97, 100, 103, 106, 108,
-      73, 78, 82, 87, 91, 95, 98, 102, 105, 109, 112, 114, 117, 119, 122, 124,
-      91, 96, 101, 105, 109, 113, 116, 119, 122, 125, 127, 128, 128, 128, 128, 128,
-      108, 113, 117, 121, 124, 127, 128, 128, 128, 128, 128, 128, 128, 128, 128, 128};
+    { 0, 0, 0, 0, 0, 0, 0, 0, 3, 5, 8, 11, 13, 16, 18, 21,
+      0, 0, 0, 3, 6, 10, 13, 16, 19, 23, 26, 29, 32, 35, 38, 41,
+      6, 10, 14, 18, 22, 26, 30, 33, 37, 41, 44, 48, 51, 54, 58, 61,
+      21, 26, 31, 35, 40, 44, 49, 53, 57, 61, 65, 68, 72, 75, 79, 82,
+      40, 45, 51, 56, 61, 66, 70, 75, 79, 83, 87, 91, 94, 98, 101, 104,
+      60, 66, 72, 77, 82, 87, 92, 96, 100, 104, 108, 111, 114, 117, 119, 121,
+      83, 89, 95, 100, 105, 109, 113, 116, 119, 122, 124,
+      104, 109, 114, 118, 121, 124};
 
 
 /******************************************************************************
@@ -286,7 +286,6 @@ e1000_set_mac_type(struct e1000_hw *hw)
     case E1000_DEV_ID_82546GB_FIBER:
     case E1000_DEV_ID_82546GB_SERDES:
     case E1000_DEV_ID_82546GB_PCIE:
-    case E1000_DEV_ID_82546GB_QUAD_COPPER:
         hw->mac_type = e1000_82546_rev_3;
         break;
     case E1000_DEV_ID_82541EI:
@@ -305,8 +304,19 @@ e1000_set_mac_type(struct e1000_hw *hw)
     case E1000_DEV_ID_82547GI:
         hw->mac_type = e1000_82547_rev_2;
         break;
+    case E1000_DEV_ID_82571EB_COPPER:
+    case E1000_DEV_ID_82571EB_FIBER:
+    case E1000_DEV_ID_82571EB_SERDES:
+            hw->mac_type = e1000_82571;
+        break;
+    case E1000_DEV_ID_82572EI_COPPER:
+    case E1000_DEV_ID_82572EI_FIBER:
+    case E1000_DEV_ID_82572EI_SERDES:
+        hw->mac_type = e1000_82572;
+        break;
     case E1000_DEV_ID_82573E:
     case E1000_DEV_ID_82573E_IAMT:
+    case E1000_DEV_ID_82573L:
         hw->mac_type = e1000_82573;
         break;
     default:
@@ -315,6 +325,8 @@ e1000_set_mac_type(struct e1000_hw *hw)
     }
 
     switch(hw->mac_type) {
+    case e1000_82571:
+    case e1000_82572:
     case e1000_82573:
         hw->eeprom_semaphore_present = TRUE;
         /* fall through */
@@ -351,6 +363,8 @@ e1000_set_media_type(struct e1000_hw *hw
     switch (hw->device_id) {
     case E1000_DEV_ID_82545GM_SERDES:
     case E1000_DEV_ID_82546GB_SERDES:
+    case E1000_DEV_ID_82571EB_SERDES:
+    case E1000_DEV_ID_82572EI_SERDES:
         hw->media_type = e1000_media_type_internal_serdes;
         break;
     default:
@@ -523,6 +537,8 @@ e1000_reset_hw(struct e1000_hw *hw)
             E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
             E1000_WRITE_FLUSH(hw);
             /* fall through */
+        case e1000_82571:
+        case e1000_82572:
             ret_val = e1000_get_auto_rd_done(hw);
             if(ret_val)
                 /* We don't want to continue accessing MAC registers. */
@@ -683,6 +699,9 @@ e1000_init_hw(struct e1000_hw *hw)
         switch (hw->mac_type) {
         default:
             break;
+        case e1000_82571:
+        case e1000_82572:
+            ctrl |= (1 << 22);
         case e1000_82573:
             ctrl |= E1000_TXDCTL_COUNT_DESC;
             break;
@@ -694,6 +713,25 @@ e1000_init_hw(struct e1000_hw *hw)
         e1000_enable_tx_pkt_filtering(hw); 
     }
 
+    switch (hw->mac_type) {
+    default:
+        break;
+    case e1000_82571:
+        ctrl = E1000_READ_REG(hw, TXDCTL1);
+        ctrl &= ~E1000_TXDCTL_WTHRESH;
+        ctrl |= E1000_TXDCTL_COUNT_DESC | E1000_TXDCTL_FULL_TX_DESC_WB;
+        ctrl |= (1 << 22);
+        E1000_WRITE_REG(hw, TXDCTL1, ctrl);
+        break;
+    }
+
+
+
+    if (hw->mac_type == e1000_82573) {
+        uint32_t gcr = E1000_READ_REG(hw, GCR);
+        gcr |= E1000_GCR_L1_ACT_WITHOUT_L0S_RX;
+        E1000_WRITE_REG(hw, GCR, gcr);
+    }
 
     /* Clear all of the statistics registers (clear on read).  It is
      * important that we do this after we have tried to establish link
@@ -878,6 +916,14 @@ e1000_setup_fiber_serdes_link(struct e10
 
     DEBUGFUNC("e1000_setup_fiber_serdes_link");
 
+    /* On 82571 and 82572 Fiber connections, SerDes loopback mode persists
+     * until explicitly turned off or a power cycle is performed.  A read to
+     * the register does not indicate its status.  Therefore, we ensure
+     * loopback mode is disabled during initialization.
+     */
+    if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572)
+        E1000_WRITE_REG(hw, SCTL, E1000_DISABLE_SERDES_LOOPBACK);
+
     /* On adapters with a MAC newer than 82544, SW Defineable pin 1 will be
      * set when the optics detect a signal. On older adapters, it will be
      * cleared when there is a signal.  This applies to fiber media only.
@@ -2943,6 +2989,8 @@ e1000_phy_reset(struct e1000_hw *hw)
 
     switch (hw->mac_type) {
     case e1000_82541_rev_2:
+    case e1000_82571:
+    case e1000_82572:
         ret_val = e1000_phy_hw_reset(hw);
         if(ret_val)
             return ret_val;
@@ -2981,6 +3029,16 @@ e1000_detect_gig_phy(struct e1000_hw *hw
 
     DEBUGFUNC("e1000_detect_gig_phy");
 
+    /* The 82571 firmware may still be configuring the PHY.  In this
+     * case, we cannot access the PHY until the configuration is done.  So
+     * we explicitly set the PHY values. */
+    if(hw->mac_type == e1000_82571 ||
+       hw->mac_type == e1000_82572) {
+        hw->phy_id = IGP01E1000_I_PHY_ID;
+        hw->phy_type = e1000_phy_igp_2;
+        return E1000_SUCCESS;
+    }
+
     /* Read the PHY ID Registers to identify which PHY is onboard. */
     ret_val = e1000_read_phy_reg(hw, PHY_ID1, &phy_id_high);
     if(ret_val)
@@ -3334,6 +3392,21 @@ e1000_init_eeprom_params(struct e1000_hw
         eeprom->use_eerd = FALSE;
         eeprom->use_eewr = FALSE;
         break;
+    case e1000_82571:
+    case e1000_82572:
+        eeprom->type = e1000_eeprom_spi;
+        eeprom->opcode_bits = 8;
+        eeprom->delay_usec = 1;
+        if (eecd & E1000_EECD_ADDR_BITS) {
+            eeprom->page_size = 32;
+            eeprom->address_bits = 16;
+        } else {
+            eeprom->page_size = 8;
+            eeprom->address_bits = 8;
+        }
+        eeprom->use_eerd = FALSE;
+        eeprom->use_eewr = FALSE;
+        break;
     case e1000_82573:
         eeprom->type = e1000_eeprom_spi;
         eeprom->opcode_bits = 8;
@@ -3543,25 +3616,26 @@ e1000_acquire_eeprom(struct e1000_hw *hw
     eecd = E1000_READ_REG(hw, EECD);
 
     if (hw->mac_type != e1000_82573) {
-    /* Request EEPROM Access */
-    if(hw->mac_type > e1000_82544) {
-        eecd |= E1000_EECD_REQ;
-        E1000_WRITE_REG(hw, EECD, eecd);
-        eecd = E1000_READ_REG(hw, EECD);
-        while((!(eecd & E1000_EECD_GNT)) &&
-              (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
-            i++;
-            udelay(5);
-            eecd = E1000_READ_REG(hw, EECD);
-        }
-        if(!(eecd & E1000_EECD_GNT)) {
-            eecd &= ~E1000_EECD_REQ;
+        /* Request EEPROM Access */
+        if(hw->mac_type > e1000_82544) {
+            eecd |= E1000_EECD_REQ;
             E1000_WRITE_REG(hw, EECD, eecd);
-            DEBUGOUT("Could not acquire EEPROM grant\n");
-            return -E1000_ERR_EEPROM;
+            eecd = E1000_READ_REG(hw, EECD);
+            while((!(eecd & E1000_EECD_GNT)) &&
+                  (i < E1000_EEPROM_GRANT_ATTEMPTS)) {
+                i++;
+                udelay(5);
+                eecd = E1000_READ_REG(hw, EECD);
+            }
+            if(!(eecd & E1000_EECD_GNT)) {
+                eecd &= ~E1000_EECD_REQ;
+                E1000_WRITE_REG(hw, EECD, eecd);
+                DEBUGOUT("Could not acquire EEPROM grant\n");
+                e1000_put_hw_eeprom_semaphore(hw);
+                return -E1000_ERR_EEPROM;
+            }
         }
     }
-    }
 
     /* Setup EEPROM for Read/Write */
 
@@ -4064,7 +4138,7 @@ e1000_write_eeprom(struct e1000_hw *hw,
         return -E1000_ERR_EEPROM;
     }
 
-    /* 82573 reads only through eerd */
+    /* 82573 writes only through eewr */
     if(eeprom->use_eewr == TRUE)
         return e1000_write_eeprom_eewr(hw, offset, words, data);
 
@@ -4353,9 +4427,16 @@ e1000_read_mac_addr(struct e1000_hw * hw
         hw->perm_mac_addr[i] = (uint8_t) (eeprom_data & 0x00FF);
         hw->perm_mac_addr[i+1] = (uint8_t) (eeprom_data >> 8);
     }
-    if(((hw->mac_type == e1000_82546) || (hw->mac_type == e1000_82546_rev_3)) &&
-       (E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1))
+    switch (hw->mac_type) {
+    default:
+        break;
+    case e1000_82546:
+    case e1000_82546_rev_3:
+    case e1000_82571:
+        if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1)
             hw->perm_mac_addr[5] ^= 0x01;
+        break;
+    }
 
     for(i = 0; i < NODE_ADDRESS_SIZE; i++)
         hw->mac_addr[i] = hw->perm_mac_addr[i];
@@ -4385,6 +4466,12 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
     e1000_rar_set(hw, hw->mac_addr, 0);
 
     rar_num = E1000_RAR_ENTRIES;
+
+    /* Reserve a spot for the Locally Administered Address to work around
+     * an 82571 issue in which a reset on one port will reload the MAC on
+     * the other port. */
+    if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
+        rar_num -= 1;
     /* Zero out the other 15 receive addresses. */
     DEBUGOUT("Clearing RAR[1-15]\n");
     for(i = 1; i < rar_num; i++) {
@@ -4427,6 +4514,12 @@ e1000_mc_addr_list_update(struct e1000_h
     /* Clear RAR[1-15] */
     DEBUGOUT(" Clearing RAR[1-15]\n");
     num_rar_entry = E1000_RAR_ENTRIES;
+    /* Reserve a spot for the Locally Administered Address to work around
+     * an 82571 issue in which a reset on one port will reload the MAC on
+     * the other port. */
+    if ((hw->mac_type == e1000_82571) && (hw->laa_is_present == TRUE))
+        num_rar_entry -= 1;
+
     for(i = rar_used_count; i < num_rar_entry; i++) {
         E1000_WRITE_REG_ARRAY(hw, RA, (i << 1), 0);
         E1000_WRITE_REG_ARRAY(hw, RA, ((i << 1) + 1), 0);
@@ -4984,7 +5077,6 @@ e1000_clear_hw_cntrs(struct e1000_hw *hw
     temp = E1000_READ_REG(hw, ICTXQEC);
     temp = E1000_READ_REG(hw, ICTXQMTC);
     temp = E1000_READ_REG(hw, ICRXDMTC);
-
 }
 
 /******************************************************************************
@@ -5151,6 +5243,8 @@ e1000_get_bus_info(struct e1000_hw *hw)
         hw->bus_speed = e1000_bus_speed_unknown;
         hw->bus_width = e1000_bus_width_unknown;
         break;
+    case e1000_82571:
+    case e1000_82572:
     case e1000_82573:
         hw->bus_type = e1000_bus_type_pci_express;
         hw->bus_speed = e1000_bus_speed_2500;
@@ -5250,6 +5344,7 @@ e1000_get_cable_length(struct e1000_hw *
     int32_t ret_val;
     uint16_t agc_value = 0;
     uint16_t cur_agc, min_agc = IGP01E1000_AGC_LENGTH_TABLE_SIZE;
+    uint16_t max_agc = 0;
     uint16_t i, phy_data;
     uint16_t cable_length;
 
@@ -5338,6 +5433,40 @@ e1000_get_cable_length(struct e1000_hw *
                        IGP01E1000_AGC_RANGE) : 0;
         *max_length = e1000_igp_cable_length_table[agc_value] +
                       IGP01E1000_AGC_RANGE;
+    } else if (hw->phy_type == e1000_phy_igp_2) {
+        uint16_t agc_reg_array[IGP02E1000_PHY_CHANNEL_NUM] =
+                                                         {IGP02E1000_PHY_AGC_A,
+                                                          IGP02E1000_PHY_AGC_B,
+                                                          IGP02E1000_PHY_AGC_C,
+                                                          IGP02E1000_PHY_AGC_D};
+        /* Read the AGC registers for all channels */
+        for (i = 0; i < IGP02E1000_PHY_CHANNEL_NUM; i++) {
+            ret_val = e1000_read_phy_reg(hw, agc_reg_array[i], &phy_data);
+            if (ret_val)
+                return ret_val;
+
+	    /* Getting bits 15:9, which represent the combination of course and
+             * fine gain values.  The result is a number that can be put into
+             * the lookup table to obtain the approximate cable length. */
+            cur_agc = (phy_data >> IGP02E1000_AGC_LENGTH_SHIFT) &
+                      IGP02E1000_AGC_LENGTH_MASK;
+
+            /* Remove min & max AGC values from calculation. */
+            if (e1000_igp_2_cable_length_table[min_agc] > e1000_igp_2_cable_length_table[cur_agc])
+                min_agc = cur_agc;
+	    if (e1000_igp_2_cable_length_table[max_agc] < e1000_igp_2_cable_length_table[cur_agc])
+                max_agc = cur_agc;
+
+            agc_value += e1000_igp_2_cable_length_table[cur_agc];
+        }
+
+        agc_value -= (e1000_igp_2_cable_length_table[min_agc] + e1000_igp_2_cable_length_table[max_agc]);
+        agc_value /= (IGP02E1000_PHY_CHANNEL_NUM - 2);
+
+        /* Calculate cable length with the error range of +/- 10 meters. */
+        *min_length = ((agc_value - IGP02E1000_AGC_RANGE) > 0) ?
+                       (agc_value - IGP02E1000_AGC_RANGE) : 0;
+        *max_length = agc_value + IGP02E1000_AGC_RANGE;
     }
 
     return E1000_SUCCESS;
@@ -6465,6 +6594,8 @@ e1000_get_auto_rd_done(struct e1000_hw *
     default:
         msec_delay(5);
         break;
+    case e1000_82571:
+    case e1000_82572:
     case e1000_82573:
         while(timeout) {
             if (E1000_READ_REG(hw, EECD) & E1000_EECD_AUTO_RD) break;
@@ -6494,10 +6625,31 @@ e1000_get_auto_rd_done(struct e1000_hw *
 int32_t
 e1000_get_phy_cfg_done(struct e1000_hw *hw)
 {
+    int32_t timeout = PHY_CFG_TIMEOUT;
+    uint32_t cfg_mask = E1000_EEPROM_CFG_DONE;
+
     DEBUGFUNC("e1000_get_phy_cfg_done");
 
-    /* Simply wait for 10ms */
-    msec_delay(10);
+    switch (hw->mac_type) {
+    default:
+        msec_delay(10);
+        break;
+    case e1000_82571:
+    case e1000_82572:
+        while (timeout) {
+            if (E1000_READ_REG(hw, EEMNGCTL) & cfg_mask)
+                break;
+            else
+                msec_delay(1);
+            timeout--;
+        }
+
+        if (!timeout) {
+            DEBUGOUT("MNG configuration cycle has not completed.\n");
+            return -E1000_ERR_RESET;
+        }
+        break;
+    }
 
     return E1000_SUCCESS;
 }
@@ -6569,8 +6721,7 @@ e1000_put_hw_eeprom_semaphore(struct e10
         return;
 
     swsm = E1000_READ_REG(hw, SWSM);
-    /* Release both semaphores. */
-    swsm &= ~(E1000_SWSM_SMBI | E1000_SWSM_SWESMBI);
+        swsm &= ~(E1000_SWSM_SWESMBI);
     E1000_WRITE_REG(hw, SWSM, swsm);
 }
 
@@ -6606,6 +6757,8 @@ e1000_arc_subsystem_valid(struct e1000_h
      * if this is the case.  We read FWSM to determine the manageability mode.
      */
     switch (hw->mac_type) {
+    case e1000_82571:
+    case e1000_82572:
     case e1000_82573:
         fwsm = E1000_READ_REG(hw, FWSM);
         if((fwsm & E1000_FWSM_MODE_MASK) != 0)
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 51c2b3a..4f2c196 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -57,6 +57,8 @@ typedef enum {
     e1000_82541_rev_2,
     e1000_82547,
     e1000_82547_rev_2,
+    e1000_82571,
+    e1000_82572,
     e1000_82573,
     e1000_num_macs
 } e1000_mac_type;
@@ -478,10 +480,16 @@ uint8_t e1000_arc_subsystem_valid(struct
 #define E1000_DEV_ID_82546GB_SERDES      0x107B
 #define E1000_DEV_ID_82546GB_PCIE        0x108A
 #define E1000_DEV_ID_82547EI             0x1019
+#define E1000_DEV_ID_82571EB_COPPER      0x105E
+#define E1000_DEV_ID_82571EB_FIBER       0x105F
+#define E1000_DEV_ID_82571EB_SERDES      0x1060
+#define E1000_DEV_ID_82572EI_COPPER      0x107D
+#define E1000_DEV_ID_82572EI_FIBER       0x107E
+#define E1000_DEV_ID_82572EI_SERDES      0x107F
 #define E1000_DEV_ID_82573E              0x108B
 #define E1000_DEV_ID_82573E_IAMT         0x108C
+#define E1000_DEV_ID_82573L              0x109A
 
-#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099
 
 #define NODE_ADDRESS_SIZE 6
 #define ETH_LENGTH_OF_ADDRESS 6
@@ -833,6 +841,8 @@ struct e1000_ffvt_entry {
 #define E1000_FFMT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
 #define E1000_FFVT_SIZE E1000_FLEXIBLE_FILTER_SIZE_MAX
 
+#define E1000_DISABLE_SERDES_LOOPBACK   0x0400
+
 /* Register Set. (82543, 82544)
  *
  * Registers are defined to be 32 bits and  should be accessed as 32 bit values.
@@ -853,6 +863,7 @@ struct e1000_ffvt_entry {
 #define E1000_CTRL_EXT 0x00018  /* Extended Device Control - RW */
 #define E1000_FLA      0x0001C  /* Flash Access - RW */
 #define E1000_MDIC     0x00020  /* MDI Control - RW */
+#define E1000_SCTL     0x00024  /* SerDes Control - RW */
 #define E1000_FCAL     0x00028  /* Flow Control Address Low - RW */
 #define E1000_FCAH     0x0002C  /* Flow Control Address High -RW */
 #define E1000_FCT      0x00030  /* Flow Control Type - RW */
@@ -864,6 +875,12 @@ struct e1000_ffvt_entry {
 #define E1000_IMC      0x000D8  /* Interrupt Mask Clear - WO */
 #define E1000_IAM      0x000E0  /* Interrupt Acknowledge Auto Mask */
 #define E1000_RCTL     0x00100  /* RX Control - RW */
+#define E1000_RDTR1    0x02820  /* RX Delay Timer (1) - RW */
+#define E1000_RDBAL1   0x02900  /* RX Descriptor Base Address Low (1) - RW */
+#define E1000_RDBAH1   0x02904  /* RX Descriptor Base Address High (1) - RW */
+#define E1000_RDLEN1   0x02908  /* RX Descriptor Length (1) - RW */
+#define E1000_RDH1     0x02910  /* RX Descriptor Head (1) - RW */
+#define E1000_RDT1     0x02918  /* RX Descriptor Tail (1) - RW */
 #define E1000_FCTTV    0x00170  /* Flow Control Transmit Timer Value - RW */
 #define E1000_TXCW     0x00178  /* TX Configuration Word - RW */
 #define E1000_RXCW     0x00180  /* RX Configuration Word - RO */
@@ -895,6 +912,12 @@ struct e1000_ffvt_entry {
 #define E1000_RDH      0x02810  /* RX Descriptor Head - RW */
 #define E1000_RDT      0x02818  /* RX Descriptor Tail - RW */
 #define E1000_RDTR     0x02820  /* RX Delay Timer - RW */
+#define E1000_RDBAL0   E1000_RDBAL /* RX Desc Base Address Low (0) - RW */
+#define E1000_RDBAH0   E1000_RDBAH /* RX Desc Base Address High (0) - RW */
+#define E1000_RDLEN0   E1000_RDLEN /* RX Desc Length (0) - RW */
+#define E1000_RDH0     E1000_RDH   /* RX Desc Head (0) - RW */
+#define E1000_RDT0     E1000_RDT   /* RX Desc Tail (0) - RW */
+#define E1000_RDTR0    E1000_RDTR  /* RX Delay Timer (0) - RW */
 #define E1000_RXDCTL   0x02828  /* RX Descriptor Control - RW */
 #define E1000_RADV     0x0282C  /* RX Interrupt Absolute Delay Timer - RW */
 #define E1000_RSRPD    0x02C00  /* RX Small Packet Detect - RW */
@@ -980,15 +1003,15 @@ struct e1000_ffvt_entry {
 #define E1000_BPTC     0x040F4  /* Broadcast Packets TX Count - R/clr */
 #define E1000_TSCTC    0x040F8  /* TCP Segmentation Context TX - R/clr */
 #define E1000_TSCTFC   0x040FC  /* TCP Segmentation Context TX Fail - R/clr */
-#define E1000_IAC       0x4100  /* Interrupt Assertion Count */
-#define E1000_ICRXPTC   0x4104  /* Interrupt Cause Rx Packet Timer Expire Count */
-#define E1000_ICRXATC   0x4108  /* Interrupt Cause Rx Absolute Timer Expire Count */
-#define E1000_ICTXPTC   0x410C  /* Interrupt Cause Tx Packet Timer Expire Count */
-#define E1000_ICTXATC   0x4110  /* Interrupt Cause Tx Absolute Timer Expire Count */
-#define E1000_ICTXQEC   0x4118  /* Interrupt Cause Tx Queue Empty Count */
-#define E1000_ICTXQMTC  0x411C  /* Interrupt Cause Tx Queue Minimum Threshold Count */
-#define E1000_ICRXDMTC  0x4120  /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
-#define E1000_ICRXOC    0x4124  /* Interrupt Cause Receiver Overrun Count */
+#define E1000_IAC      0x04100  /* Interrupt Assertion Count */
+#define E1000_ICRXPTC  0x04104  /* Interrupt Cause Rx Packet Timer Expire Count */
+#define E1000_ICRXATC  0x04108  /* Interrupt Cause Rx Absolute Timer Expire Count */
+#define E1000_ICTXPTC  0x0410C  /* Interrupt Cause Tx Packet Timer Expire Count */
+#define E1000_ICTXATC  0x04110  /* Interrupt Cause Tx Absolute Timer Expire Count */
+#define E1000_ICTXQEC  0x04118  /* Interrupt Cause Tx Queue Empty Count */
+#define E1000_ICTXQMTC 0x0411C  /* Interrupt Cause Tx Queue Minimum Threshold Count */
+#define E1000_ICRXDMTC 0x04120  /* Interrupt Cause Rx Descriptor Minimum Threshold Count */
+#define E1000_ICRXOC   0x04124  /* Interrupt Cause Receiver Overrun Count */
 #define E1000_RXCSUM   0x05000  /* RX Checksum Control - RW */
 #define E1000_RFCTL    0x05008  /* Receive Filter Control*/
 #define E1000_MTA      0x05200  /* Multicast Table Array - RW Array */
@@ -1018,6 +1041,14 @@ struct e1000_ffvt_entry {
 #define E1000_FWSM      0x05B54 /* FW Semaphore */
 #define E1000_FFLT_DBG  0x05F04 /* Debug Register */
 #define E1000_HICR      0x08F00 /* Host Inteface Control */
+
+/* RSS registers */
+#define E1000_CPUVEC    0x02C10 /* CPU Vector Register - RW */
+#define E1000_MRQC      0x05818 /* Multiple Receive Control - RW */
+#define E1000_RETA      0x05C00 /* Redirection Table - RW Array */
+#define E1000_RSSRK     0x05C80 /* RSS Random Key - RW Array */
+#define E1000_RSSIM     0x05864 /* RSS Interrupt Mask */
+#define E1000_RSSIR     0x05868 /* RSS Interrupt Request */
 /* Register Set (82542)
  *
  * Some of the 82542 registers are located at different offsets than they are
@@ -1032,6 +1063,7 @@ struct e1000_ffvt_entry {
 #define E1000_82542_CTRL_EXT E1000_CTRL_EXT
 #define E1000_82542_FLA      E1000_FLA
 #define E1000_82542_MDIC     E1000_MDIC
+#define E1000_82542_SCTL     E1000_SCTL
 #define E1000_82542_FCAL     E1000_FCAL
 #define E1000_82542_FCAH     E1000_FCAH
 #define E1000_82542_FCT      E1000_FCT
@@ -1049,6 +1081,18 @@ struct e1000_ffvt_entry {
 #define E1000_82542_RDLEN    0x00118
 #define E1000_82542_RDH      0x00120
 #define E1000_82542_RDT      0x00128
+#define E1000_82542_RDTR0    E1000_82542_RDTR
+#define E1000_82542_RDBAL0   E1000_82542_RDBAL
+#define E1000_82542_RDBAH0   E1000_82542_RDBAH
+#define E1000_82542_RDLEN0   E1000_82542_RDLEN
+#define E1000_82542_RDH0     E1000_82542_RDH
+#define E1000_82542_RDT0     E1000_82542_RDT
+#define E1000_82542_RDTR1    0x00130
+#define E1000_82542_RDBAL1   0x00138
+#define E1000_82542_RDBAH1   0x0013C
+#define E1000_82542_RDLEN1   0x00140
+#define E1000_82542_RDH1     0x00148
+#define E1000_82542_RDT1     0x00150
 #define E1000_82542_FCRTH    0x00160
 #define E1000_82542_FCRTL    0x00168
 #define E1000_82542_FCTTV    E1000_FCTTV
@@ -1197,6 +1241,13 @@ struct e1000_ffvt_entry {
 #define E1000_82542_ICRXOC      E1000_ICRXOC
 #define E1000_82542_HICR        E1000_HICR
 
+#define E1000_82542_CPUVEC      E1000_CPUVEC
+#define E1000_82542_MRQC        E1000_MRQC
+#define E1000_82542_RETA        E1000_RETA
+#define E1000_82542_RSSRK       E1000_RSSRK
+#define E1000_82542_RSSIM       E1000_RSSIM
+#define E1000_82542_RSSIR       E1000_RSSIR
+
 /* Statistics counters collected by the MAC */
 struct e1000_hw_stats {
     uint64_t crcerrs;
@@ -1336,6 +1387,7 @@ struct e1000_hw {
     boolean_t serdes_link_down;
     boolean_t tbi_compatibility_en;
     boolean_t tbi_compatibility_on;
+    boolean_t laa_is_present;
     boolean_t phy_reset_disable;
     boolean_t fc_send_xon;
     boolean_t fc_strict_ieee;
@@ -1374,6 +1426,7 @@ struct e1000_hw {
 #define E1000_CTRL_BEM32    0x00000400  /* Big Endian 32 mode */
 #define E1000_CTRL_FRCSPD   0x00000800  /* Force Speed */
 #define E1000_CTRL_FRCDPX   0x00001000  /* Force Duplex */
+#define E1000_CTRL_D_UD_EN  0x00002000  /* Dock/Undock enable */
 #define E1000_CTRL_D_UD_POLARITY 0x00004000 /* Defined polarity of Dock/Undock indication in SDP[0] */
 #define E1000_CTRL_SWDPIN0  0x00040000  /* SWDPIN 0 value */
 #define E1000_CTRL_SWDPIN1  0x00080000  /* SWDPIN 1 value */
@@ -1491,6 +1544,8 @@ struct e1000_hw {
 #define E1000_CTRL_EXT_WR_WMARK_320   0x01000000
 #define E1000_CTRL_EXT_WR_WMARK_384   0x02000000
 #define E1000_CTRL_EXT_WR_WMARK_448   0x03000000
+#define E1000_CTRL_EXT_CANC           0x04000000  /* Interrupt delay cancellation */
+#define E1000_CTRL_EXT_DRV_LOAD       0x10000000  /* Driver loaded bit for FW */
 #define E1000_CTRL_EXT_IAME           0x08000000  /* Interrupt acknowledge Auto-mask */
 #define E1000_CTRL_EXT_INT_TIMER_CLR  0x20000000  /* Clear Interrupt timers after IMS clear */
 
@@ -1524,6 +1579,7 @@ struct e1000_hw {
 #define E1000_LEDCTL_LED2_BLINK           0x00800000
 #define E1000_LEDCTL_LED3_MODE_MASK       0x0F000000
 #define E1000_LEDCTL_LED3_MODE_SHIFT      24
+#define E1000_LEDCTL_LED3_BLINK_RATE      0x20000000
 #define E1000_LEDCTL_LED3_IVRT            0x40000000
 #define E1000_LEDCTL_LED3_BLINK           0x80000000
 
@@ -1784,6 +1840,16 @@ struct e1000_hw {
 #define E1000_RXCSUM_IPPCSE    0x00001000   /* IP payload checksum enable */
 #define E1000_RXCSUM_PCSD      0x00002000   /* packet checksum disabled */
 
+/* Multiple Receive Queue Control */
+#define E1000_MRQC_ENABLE_MASK              0x00000003
+#define E1000_MRQC_ENABLE_RSS_2Q            0x00000001
+#define E1000_MRQC_ENABLE_RSS_INT           0x00000004
+#define E1000_MRQC_RSS_FIELD_MASK           0xFFFF0000
+#define E1000_MRQC_RSS_FIELD_IPV4_TCP       0x00010000
+#define E1000_MRQC_RSS_FIELD_IPV4           0x00020000
+#define E1000_MRQC_RSS_FIELD_IPV6_TCP       0x00040000
+#define E1000_MRQC_RSS_FIELD_IPV6_EX        0x00080000
+#define E1000_MRQC_RSS_FIELD_IPV6           0x00100000
 
 /* Definitions for power management and wakeup registers */
 /* Wake Up Control */
@@ -1928,6 +1994,7 @@ struct e1000_host_command_info {
 #define E1000_MDALIGN          4096
 
 #define E1000_GCR_BEM32                 0x00400000
+#define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000
 /* Function Active and Power State to MNG */
 #define E1000_FACTPS_FUNC0_POWER_STATE_MASK         0x00000003
 #define E1000_FACTPS_LAN0_VALID                     0x00000004
@@ -1980,6 +2047,7 @@ struct e1000_host_command_info {
 /* EEPROM Word Offsets */
 #define EEPROM_COMPAT                 0x0003
 #define EEPROM_ID_LED_SETTINGS        0x0004
+#define EEPROM_VERSION                0x0005
 #define EEPROM_SERDES_AMPLITUDE       0x0006 /* For SERDES output amplitude adjustment. */
 #define EEPROM_PHY_CLASS_WORD         0x0007
 #define EEPROM_INIT_CONTROL1_REG      0x000A
@@ -1990,6 +2058,8 @@ struct e1000_host_command_info {
 #define EEPROM_FLASH_VERSION          0x0032
 #define EEPROM_CHECKSUM_REG           0x003F
 
+#define E1000_EEPROM_CFG_DONE         0x00040000   /* MNG config cycle done */
+
 /* Word definitions for ID LED Settings */
 #define ID_LED_RESERVED_0000 0x0000
 #define ID_LED_RESERVED_FFFF 0xFFFF
@@ -2108,6 +2178,8 @@ struct e1000_host_command_info {
 #define E1000_PBA_22K 0x0016
 #define E1000_PBA_24K 0x0018
 #define E1000_PBA_30K 0x001E
+#define E1000_PBA_32K 0x0020
+#define E1000_PBA_38K 0x0026
 #define E1000_PBA_40K 0x0028
 #define E1000_PBA_48K 0x0030    /* 48KB, default RX allocation */
 
@@ -2592,11 +2664,11 @@ struct e1000_host_command_info {
 
 /* 7 bits (3 Coarse + 4 Fine) --> 128 optional values */
 #define IGP01E1000_AGC_LENGTH_TABLE_SIZE 128
-#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 128
+#define IGP02E1000_AGC_LENGTH_TABLE_SIZE 113
 
 /* The precision error of the cable length is +/- 10 meters */
 #define IGP01E1000_AGC_RANGE    10
-#define IGP02E1000_AGC_RANGE    10
+#define IGP02E1000_AGC_RANGE    15
 
 /* IGP01E1000 PCS Initialization register */
 /* bits 3:6 in the PCS registers stores the channels polarity */
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index c062b0a..407abb2 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -398,6 +398,10 @@ e1000_reset(struct e1000_adapter *adapte
 	case e1000_82547_rev_2:
 		pba = E1000_PBA_30K;
 		break;
+	case e1000_82571:
+	case e1000_82572:
+		pba = E1000_PBA_38K;
+		break;
 	case e1000_82573:
 		pba = E1000_PBA_12K;
 		break;
@@ -475,6 +479,7 @@ e1000_probe(struct pci_dev *pdev,
 	struct net_device *netdev;
 	struct e1000_adapter *adapter;
 	unsigned long mmio_start, mmio_len;
+	uint32_t ctrl_ext;
 	uint32_t swsm;
 
 	static int cards_found = 0;
@@ -688,6 +693,12 @@ e1000_probe(struct pci_dev *pdev,
 
 	/* Let firmware know the driver has taken over */
 	switch(adapter->hw.mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+		break;
 	case e1000_82573:
 		swsm = E1000_READ_REG(&adapter->hw, SWSM);
 		E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -732,6 +743,7 @@ e1000_remove(struct pci_dev *pdev)
 {
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
+	uint32_t ctrl_ext;
 	uint32_t manc, swsm;
 
 	flush_scheduled_work();
@@ -746,6 +758,12 @@ e1000_remove(struct pci_dev *pdev)
 	}
 
 	switch(adapter->hw.mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+		break;
 	case e1000_82573:
 		swsm = E1000_READ_REG(&adapter->hw, SWSM);
 		E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -1236,7 +1254,7 @@ e1000_setup_rctl(struct e1000_adapter *a
 		rctl |= E1000_RCTL_LPE;
 
 	/* Setup buffer sizes */
-	if(adapter->hw.mac_type == e1000_82573) {
+	if(adapter->hw.mac_type >= e1000_82571) {
 		/* We can now specify buffers in 1K increments.
 		 * BSIZE and BSEX are ignored in this case. */
 		rctl |= adapter->rx_buffer_len << 0x11;
@@ -1352,7 +1370,7 @@ e1000_configure_rx(struct e1000_adapter 
 		if(adapter->rx_csum == TRUE) {
 			rxcsum |= E1000_RXCSUM_TUOFL;
 
-			/* Enable 82573 IPv4 payload checksum for UDP fragments
+			/* Enable 82571 IPv4 payload checksum for UDP fragments
 			 * Must be used in conjunction with packet-split. */
 			if((adapter->hw.mac_type > e1000_82547_rev_2) && 
 			   (adapter->rx_ps)) {
@@ -1608,6 +1626,22 @@ e1000_set_mac(struct net_device *netdev,
 
 	e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
 
+	/* With 82571 controllers, LAA may be overwritten (with the default)
+	 * due to controller reset from the other port. */
+	if (adapter->hw.mac_type == e1000_82571) {
+		/* activate the work around */
+		adapter->hw.laa_is_present = 1;
+
+		/* Hold a copy of the LAA in RAR[14] This is done so that 
+		 * between the time RAR[0] gets clobbered  and the time it 
+		 * gets fixed (in e1000_watchdog), the actual LAA is in one 
+		 * of the RARs and no incoming packets directed to this port
+		 * are dropped. Eventaully the LAA will be in RAR[0] and 
+		 * RAR[14] */
+		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 
+					E1000_RAR_ENTRIES - 1);
+	}
+
 	if(adapter->hw.mac_type == e1000_82542_rev2_0)
 		e1000_leave_82542_rst(adapter);
 
@@ -1633,9 +1667,12 @@ e1000_set_multi(struct net_device *netde
 	unsigned long flags;
 	uint32_t rctl;
 	uint32_t hash_value;
-	int i;
+	int i, rar_entries = E1000_RAR_ENTRIES;
 
 	spin_lock_irqsave(&adapter->tx_lock, flags);
+	/* reserve RAR[14] for LAA over-write work-around */
+	if (adapter->hw.mac_type == e1000_82571)
+		rar_entries--;
 
 	/* Check for Promiscuous and All Multicast modes */
 
@@ -1660,11 +1697,12 @@ e1000_set_multi(struct net_device *netde
 	/* load the first 14 multicast address into the exact filters 1-14
 	 * RAR 0 is used for the station MAC adddress
 	 * if there are not 14 addresses, go ahead and clear the filters
+	 * -- with 82571 controllers only 0-13 entries are filled here
 	 */
 	mc_ptr = netdev->mc_list;
 
-	for(i = 1; i < E1000_RAR_ENTRIES; i++) {
-		if(mc_ptr) {
+	for(i = 1; i < rar_entries; i++) {
+		if (mc_ptr) {
 			e1000_rar_set(hw, mc_ptr->dmi_addr, i);
 			mc_ptr = mc_ptr->next;
 		} else {
@@ -1848,6 +1886,11 @@ e1000_watchdog_task(struct e1000_adapter
 	/* Force detection of hung controller every watchdog period */
 	adapter->detect_tx_hung = TRUE;
 
+	/* With 82571 controllers, LAA may be overwritten due to controller 
+	 * reset from the other port. Set the appropriate LAA in RAR[0] */
+	if (adapter->hw.mac_type == e1000_82571 && adapter->hw.laa_is_present)
+		e1000_rar_set(&adapter->hw, adapter->hw.mac_addr, 0);
+
 	/* Reset the timer */
 	mod_timer(&adapter->watchdog_timer, jiffies + 2 * HZ);
 }
@@ -2269,6 +2312,27 @@ e1000_xmit_frame(struct sk_buff *skb, st
  		local_irq_restore(flags); 
  		return NETDEV_TX_LOCKED; 
  	} 
+#ifdef NETIF_F_TSO
+	/* TSO Workaround for 82571/2 Controllers -- if skb->data
+	 * points to just header, pull a few bytes of payload from 
+	 * frags into skb->data */
+	if (skb_shinfo(skb)->tso_size) {
+		uint8_t hdr_len;
+		hdr_len = ((skb->h.raw - skb->data) + (skb->h.th->doff << 2));
+		if (skb->data_len && (hdr_len < (skb->len - skb->data_len)) && 
+			(adapter->hw.mac_type == e1000_82571 ||
+			adapter->hw.mac_type == e1000_82572)) {
+			unsigned int pull_size;
+			pull_size = min((unsigned int)4, skb->data_len);
+			if (!__pskb_pull_tail(skb, pull_size)) {
+				printk(KERN_ERR "__pskb_pull_tail failed.\n");
+				dev_kfree_skb_any(skb);
+				return -EFAULT;
+			}
+		}
+	}
+#endif
+
 	if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
 		e1000_transfer_dhcp_info(adapter, skb);
 
@@ -2310,7 +2374,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
 	/* Old method was to assume IPv4 packet by default if TSO was enabled.
-	 * 82573 hardware supports TSO capabilities for IPv6 as well...
+	 * 82571 hardware supports TSO capabilities for IPv6 as well...
 	 * no longer assume, we must. */
 	if(likely(skb->protocol == ntohs(ETH_P_IP)))
 		tx_flags |= E1000_TX_FLAGS_IPV4;
@@ -2389,9 +2453,18 @@ e1000_change_mtu(struct net_device *netd
 			return -EINVAL;
 	}
 
-#define MAX_STD_JUMBO_FRAME_SIZE 9216
+#define MAX_STD_JUMBO_FRAME_SIZE 9234
 	/* might want this to be bigger enum check... */
-	if (adapter->hw.mac_type == e1000_82573 &&
+	/* 82571 controllers limit jumbo frame size to 10500 bytes */
+	if ((adapter->hw.mac_type == e1000_82571 || 
+	     adapter->hw.mac_type == e1000_82572) &&
+	    max_frame > MAX_STD_JUMBO_FRAME_SIZE) {
+		DPRINTK(PROBE, ERR, "MTU > 9216 bytes not supported "
+				    "on 82571 and 82572 controllers.\n");
+		return -EINVAL;
+	}
+
+	if(adapter->hw.mac_type == e1000_82573 &&
 	    max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) {
 		DPRINTK(PROBE, ERR, "Jumbo Frames not supported "
 				    "on 82573\n");
@@ -3716,6 +3789,12 @@ e1000_suspend(struct pci_dev *pdev, pm_m
 	}
 
 	switch(adapter->hw.mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+				ctrl_ext & ~E1000_CTRL_EXT_DRV_LOAD);
+		break;
 	case e1000_82573:
 		swsm = E1000_READ_REG(&adapter->hw, SWSM);
 		E1000_WRITE_REG(&adapter->hw, SWSM,
@@ -3738,6 +3817,7 @@ e1000_resume(struct pci_dev *pdev)
 	struct net_device *netdev = pci_get_drvdata(pdev);
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	uint32_t manc, ret_val, swsm;
+	uint32_t ctrl_ext;
 
 	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
@@ -3763,6 +3843,12 @@ e1000_resume(struct pci_dev *pdev)
 	}
 
 	switch(adapter->hw.mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+		ctrl_ext = E1000_READ_REG(&adapter->hw, CTRL_EXT);
+		E1000_WRITE_REG(&adapter->hw, CTRL_EXT,
+				ctrl_ext | E1000_CTRL_EXT_DRV_LOAD);
+		break;
 	case e1000_82573:
 		swsm = E1000_READ_REG(&adapter->hw, SWSM);
 		E1000_WRITE_REG(&adapter->hw, SWSM,
---
0.99.8.GIT


--- NEW FILE 0357-e1000-multi-queue-defines-modification-to-data-structures.txt ---
Subject: [PATCH] e1000: multi-queue defines/modification to data structures
From: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Date: 1128423715 -0400

defines/modifies data structures, function prototypes and changes to the
driver rendering it capable of handling <n> tx/rx queues

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan at intel.com>
Signed-off-by: John Ronciak <john.ronciak at intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000.h         |   67 +++-
 drivers/net/e1000/e1000_ethtool.c |   75 +++-
 drivers/net/e1000/e1000_main.c    |  655 +++++++++++++++++++++++++------------
 drivers/net/e1000/e1000_param.c   |   10 -
 4 files changed, 564 insertions(+), 243 deletions(-)

applies-to: c251bfd8341b6bf30064dd0ae50d790d8df65f7e
581d708eb47cccb5f41bc0817e50c9b004011ba8
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 092757b..9b7274b 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -72,6 +72,10 @@
 #include <linux/mii.h>
 #include <linux/ethtool.h>
 #include <linux/if_vlan.h>
+#ifdef CONFIG_E1000_MQ
+#include <linux/cpu.h>
+#include <linux/smp.h>
+#endif
 
 #define BAR_0		0
 #define BAR_1		1
@@ -168,7 +172,30 @@ struct e1000_buffer {
 struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; };
 struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; };
 
-struct e1000_desc_ring {
+struct e1000_tx_ring {
+	/* pointer to the descriptor ring memory */
+	void *desc;
+	/* physical address of the descriptor ring */
+	dma_addr_t dma;
+	/* length of descriptor ring in bytes */
+	unsigned int size;
+	/* number of descriptors in the ring */
+	unsigned int count;
+	/* next descriptor to associate a buffer with */
+	unsigned int next_to_use;
+	/* next descriptor to check for DD status bit */
+	unsigned int next_to_clean;
+	/* array of buffer information structs */
+	struct e1000_buffer *buffer_info;
+
+	struct e1000_buffer previous_buffer_info;
+	spinlock_t tx_lock;
+	uint16_t tdh;
+	uint16_t tdt;
+	uint64_t pkt;
+};
+
+struct e1000_rx_ring {
 	/* pointer to the descriptor ring memory */
 	void *desc;
 	/* physical address of the descriptor ring */
@@ -186,6 +213,10 @@ struct e1000_desc_ring {
 	/* arrays of page information for packet split */
 	struct e1000_ps_page *ps_page;
 	struct e1000_ps_page_dma *ps_page_dma;
+
+	uint16_t rdh;
+	uint16_t rdt;
+	uint64_t pkt;
 };
 
 #define E1000_DESC_UNUSED(R) \
@@ -227,9 +258,10 @@ struct e1000_adapter {
 	unsigned long led_status;
 
 	/* TX */
-	struct e1000_desc_ring tx_ring;
-	struct e1000_buffer previous_buffer_info;
-	spinlock_t tx_lock;
+	struct e1000_tx_ring *tx_ring;      /* One per active queue */
+#ifdef CONFIG_E1000_MQ
+	struct e1000_tx_ring **cpu_tx_ring; /* per-cpu */
+#endif
 	uint32_t txd_cmd;
 	uint32_t tx_int_delay;
 	uint32_t tx_abs_int_delay;
@@ -246,13 +278,26 @@ struct e1000_adapter {
 
 	/* RX */
 #ifdef CONFIG_E1000_NAPI
-	boolean_t (*clean_rx) (struct e1000_adapter *adapter, int *work_done,
-			  int work_to_do);
+	boolean_t (*clean_rx) (struct e1000_adapter *adapter,
+			       struct e1000_rx_ring *rx_ring,
+			       int *work_done, int work_to_do);
 #else
-	boolean_t (*clean_rx) (struct e1000_adapter *adapter);
+	boolean_t (*clean_rx) (struct e1000_adapter *adapter,
+			       struct e1000_rx_ring *rx_ring);
 #endif
-	void (*alloc_rx_buf) (struct e1000_adapter *adapter);
-	struct e1000_desc_ring rx_ring;
+	void (*alloc_rx_buf) (struct e1000_adapter *adapter,
+			      struct e1000_rx_ring *rx_ring);
+	struct e1000_rx_ring *rx_ring;      /* One per active queue */
+#ifdef CONFIG_E1000_NAPI
+	struct net_device *polling_netdev;  /* One per active queue */
+#endif
+#ifdef CONFIG_E1000_MQ
+	struct net_device **cpu_netdev;     /* per-cpu */
+	struct call_async_data_struct rx_sched_call_data;
+	int cpu_for_queue[4];
+#endif
+	int num_queues;
+
 	uint64_t hw_csum_err;
 	uint64_t hw_csum_good;
 	uint32_t rx_int_delay;
@@ -278,8 +323,8 @@ struct e1000_adapter {
 	struct e1000_phy_stats phy_stats;
 
 	uint32_t test_icr;
-	struct e1000_desc_ring test_tx_ring;
-	struct e1000_desc_ring test_rx_ring;
+	struct e1000_tx_ring test_tx_ring;
+	struct e1000_rx_ring test_rx_ring;
 
 
 	int msg_enable;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 5f9a36b..6e7e34f 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -39,10 +39,10 @@ extern int e1000_up(struct e1000_adapter
 extern void e1000_down(struct e1000_adapter *adapter);
 extern void e1000_reset(struct e1000_adapter *adapter);
 extern int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-extern int e1000_setup_rx_resources(struct e1000_adapter *adapter);
-extern int e1000_setup_tx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_rx_resources(struct e1000_adapter *adapter);
-extern void e1000_free_tx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+extern int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+extern void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
 extern void e1000_update_stats(struct e1000_adapter *adapter);
 
 struct e1000_stats {
@@ -576,8 +576,8 @@ e1000_get_ringparam(struct net_device *n
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	e1000_mac_type mac_type = adapter->hw.mac_type;
-	struct e1000_desc_ring *txdr = &adapter->tx_ring;
-	struct e1000_desc_ring *rxdr = &adapter->rx_ring;
+	struct e1000_tx_ring *txdr = adapter->tx_ring;
+	struct e1000_rx_ring *rxdr = adapter->rx_ring;
 
 	ring->rx_max_pending = (mac_type < e1000_82544) ? E1000_MAX_RXD :
 		E1000_MAX_82544_RXD;
@@ -597,20 +597,40 @@ e1000_set_ringparam(struct net_device *n
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	e1000_mac_type mac_type = adapter->hw.mac_type;
-	struct e1000_desc_ring *txdr = &adapter->tx_ring;
-	struct e1000_desc_ring *rxdr = &adapter->rx_ring;
-	struct e1000_desc_ring tx_old, tx_new, rx_old, rx_new;
-	int err;
+	struct e1000_tx_ring *txdr, *tx_old, *tx_new;
+	struct e1000_rx_ring *rxdr, *rx_old, *rx_new;
+	int i, err, tx_ring_size, rx_ring_size;
+
+	tx_ring_size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
+	rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+
+	if (netif_running(adapter->netdev))
+		e1000_down(adapter);
 
 	tx_old = adapter->tx_ring;
 	rx_old = adapter->rx_ring;
 
+	adapter->tx_ring = kmalloc(tx_ring_size, GFP_KERNEL);
+	if (!adapter->tx_ring) {
+		err = -ENOMEM;
+		goto err_setup_rx;
+	}
+	memset(adapter->tx_ring, 0, tx_ring_size);
+
+	adapter->rx_ring = kmalloc(rx_ring_size, GFP_KERNEL);
+	if (!adapter->rx_ring) {
+		kfree(adapter->tx_ring);
+		err = -ENOMEM;
+		goto err_setup_rx;
+	}
+	memset(adapter->rx_ring, 0, rx_ring_size);
+
+	txdr = adapter->tx_ring;
+	rxdr = adapter->rx_ring;
+
 	if((ring->rx_mini_pending) || (ring->rx_jumbo_pending))
 		return -EINVAL;
 
-	if(netif_running(adapter->netdev))
-		e1000_down(adapter);
-
 	rxdr->count = max(ring->rx_pending,(uint32_t)E1000_MIN_RXD);
 	rxdr->count = min(rxdr->count,(uint32_t)(mac_type < e1000_82544 ?
 		E1000_MAX_RXD : E1000_MAX_82544_RXD));
@@ -621,11 +641,16 @@ e1000_set_ringparam(struct net_device *n
 		E1000_MAX_TXD : E1000_MAX_82544_TXD));
 	E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); 
 
+	for (i = 0; i < adapter->num_queues; i++) {
+		txdr[i].count = txdr->count;
+		rxdr[i].count = rxdr->count;
+	}
+
 	if(netif_running(adapter->netdev)) {
 		/* Try to get new resources before deleting old */
-		if((err = e1000_setup_rx_resources(adapter)))
+		if ((err = e1000_setup_all_rx_resources(adapter)))
 			goto err_setup_rx;
-		if((err = e1000_setup_tx_resources(adapter)))
+		if ((err = e1000_setup_all_tx_resources(adapter)))
 			goto err_setup_tx;
 
 		/* save the new, restore the old in order to free it,
@@ -635,8 +660,10 @@ e1000_set_ringparam(struct net_device *n
 		tx_new = adapter->tx_ring;
 		adapter->rx_ring = rx_old;
 		adapter->tx_ring = tx_old;
-		e1000_free_rx_resources(adapter);
-		e1000_free_tx_resources(adapter);
+		e1000_free_all_rx_resources(adapter);
+		e1000_free_all_tx_resources(adapter);
+		kfree(tx_old);
+		kfree(rx_old);
 		adapter->rx_ring = rx_new;
 		adapter->tx_ring = tx_new;
 		if((err = e1000_up(adapter)))
@@ -645,7 +672,7 @@ e1000_set_ringparam(struct net_device *n
 
 	return 0;
 err_setup_tx:
-	e1000_free_rx_resources(adapter);
+	e1000_free_all_rx_resources(adapter);
 err_setup_rx:
 	adapter->rx_ring = rx_old;
 	adapter->tx_ring = tx_old;
@@ -903,8 +930,8 @@ e1000_intr_test(struct e1000_adapter *ad
 static void
 e1000_free_desc_rings(struct e1000_adapter *adapter)
 {
-	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
-	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+	struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+	struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int i;
 
@@ -946,8 +973,8 @@ e1000_free_desc_rings(struct e1000_adapt
 static int
 e1000_setup_desc_rings(struct e1000_adapter *adapter)
 {
-	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
-	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+	struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+	struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	uint32_t rctl;
 	int size, i, ret_val;
@@ -1347,8 +1374,8 @@ e1000_check_lbtest_frame(struct sk_buff 
 static int
 e1000_run_loopback_test(struct e1000_adapter *adapter)
 {
-	struct e1000_desc_ring *txdr = &adapter->test_tx_ring;
-	struct e1000_desc_ring *rxdr = &adapter->test_rx_ring;
+	struct e1000_tx_ring *txdr = &adapter->test_tx_ring;
+	struct e1000_rx_ring *rxdr = &adapter->test_rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int i, j, k, l, lc, good_cnt, ret_val=0;
 	unsigned long time;
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 407abb2..5145b73 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -102,10 +102,18 @@ int e1000_up(struct e1000_adapter *adapt
 void e1000_down(struct e1000_adapter *adapter);
 void e1000_reset(struct e1000_adapter *adapter);
 int e1000_set_spd_dplx(struct e1000_adapter *adapter, uint16_t spddplx);
-int e1000_setup_tx_resources(struct e1000_adapter *adapter);
-int e1000_setup_rx_resources(struct e1000_adapter *adapter);
-void e1000_free_tx_resources(struct e1000_adapter *adapter);
-void e1000_free_rx_resources(struct e1000_adapter *adapter);
+int e1000_setup_all_tx_resources(struct e1000_adapter *adapter);
+int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
+void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
+int e1000_setup_tx_resources(struct e1000_adapter *adapter,
+                             struct e1000_tx_ring *txdr);
+int e1000_setup_rx_resources(struct e1000_adapter *adapter,
+                             struct e1000_rx_ring *rxdr);
+void e1000_free_tx_resources(struct e1000_adapter *adapter,
+                             struct e1000_tx_ring *tx_ring);
+void e1000_free_rx_resources(struct e1000_adapter *adapter,
+                             struct e1000_rx_ring *rx_ring);
 void e1000_update_stats(struct e1000_adapter *adapter);
 
 /* Local Function Prototypes */
@@ -114,14 +122,22 @@ static int e1000_init_module(void);
 static void e1000_exit_module(void);
 static int e1000_probe(struct pci_dev *pdev, const struct pci_device_id *ent);
 static void __devexit e1000_remove(struct pci_dev *pdev);
+static int e1000_alloc_queues(struct e1000_adapter *adapter);
+#ifdef CONFIG_E1000_MQ
+static void e1000_setup_queue_mapping(struct e1000_adapter *adapter);
+#endif
 static int e1000_sw_init(struct e1000_adapter *adapter);
 static int e1000_open(struct net_device *netdev);
 static int e1000_close(struct net_device *netdev);
 static void e1000_configure_tx(struct e1000_adapter *adapter);
 static void e1000_configure_rx(struct e1000_adapter *adapter);
 static void e1000_setup_rctl(struct e1000_adapter *adapter);
-static void e1000_clean_tx_ring(struct e1000_adapter *adapter);
-static void e1000_clean_rx_ring(struct e1000_adapter *adapter);
+static void e1000_clean_all_tx_rings(struct e1000_adapter *adapter);
+static void e1000_clean_all_rx_rings(struct e1000_adapter *adapter);
+static void e1000_clean_tx_ring(struct e1000_adapter *adapter,
+                                struct e1000_tx_ring *tx_ring);
+static void e1000_clean_rx_ring(struct e1000_adapter *adapter,
+                                struct e1000_rx_ring *rx_ring);
 static void e1000_set_multi(struct net_device *netdev);
 static void e1000_update_phy_info(unsigned long data);
 static void e1000_watchdog(unsigned long data);
@@ -132,19 +148,26 @@ static struct net_device_stats * e1000_g
 static int e1000_change_mtu(struct net_device *netdev, int new_mtu);
 static int e1000_set_mac(struct net_device *netdev, void *p);
 static irqreturn_t e1000_intr(int irq, void *data, struct pt_regs *regs);
-static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter);
+static boolean_t e1000_clean_tx_irq(struct e1000_adapter *adapter,
+                                    struct e1000_tx_ring *tx_ring);
 #ifdef CONFIG_E1000_NAPI
-static int e1000_clean(struct net_device *netdev, int *budget);
+static int e1000_clean(struct net_device *poll_dev, int *budget);
 static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
+                                    struct e1000_rx_ring *rx_ring,
                                     int *work_done, int work_to_do);
 static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+                                       struct e1000_rx_ring *rx_ring,
                                        int *work_done, int work_to_do);
 #else
-static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter);
-static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter);
+static boolean_t e1000_clean_rx_irq(struct e1000_adapter *adapter,
+                                    struct e1000_rx_ring *rx_ring);
+static boolean_t e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+                                       struct e1000_rx_ring *rx_ring);
 #endif
-static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter);
-static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter);
+static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
+                                   struct e1000_rx_ring *rx_ring);
+static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
+                                      struct e1000_rx_ring *rx_ring);
 static int e1000_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd);
 static int e1000_mii_ioctl(struct net_device *netdev, struct ifreq *ifr,
 			   int cmd);
@@ -289,7 +312,7 @@ int
 e1000_up(struct e1000_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	int err;
+	int i, err;
 
 	/* hardware has been reset, we need to reload some things */
 
@@ -308,7 +331,8 @@ e1000_up(struct e1000_adapter *adapter)
 	e1000_configure_tx(adapter);
 	e1000_setup_rctl(adapter);
 	e1000_configure_rx(adapter);
-	adapter->alloc_rx_buf(adapter);
+	for (i = 0; i < adapter->num_queues; i++)
+		adapter->alloc_rx_buf(adapter, &adapter->rx_ring[i]);
 
 #ifdef CONFIG_PCI_MSI
 	if(adapter->hw.mac_type > e1000_82547_rev_2) {
@@ -363,8 +387,8 @@ e1000_down(struct e1000_adapter *adapter
 	netif_stop_queue(netdev);
 
 	e1000_reset(adapter);
-	e1000_clean_tx_ring(adapter);
-	e1000_clean_rx_ring(adapter);
+	e1000_clean_all_tx_rings(adapter);
+	e1000_clean_all_rx_rings(adapter);
 
 	/* If WoL is not enabled
 	 * and management mode is not IAMT
@@ -747,6 +771,9 @@ e1000_remove(struct pci_dev *pdev)
 	uint32_t manc, swsm;
 
 	flush_scheduled_work();
+#ifdef CONFIG_E1000_NAPI
+	int i;
+#endif
 
 	if(adapter->hw.mac_type >= e1000_82540 &&
 	   adapter->hw.media_type == e1000_media_type_copper) {
@@ -775,6 +802,10 @@ e1000_remove(struct pci_dev *pdev)
 	}
 
 	unregister_netdev(netdev);
+#ifdef CONFIG_E1000_NAPI
+	for (i = 0; i < adapter->num_queues; i++)
+		__dev_put(&adapter->polling_netdev[i]);
+#endif
 
 	if(!e1000_check_phy_reset_block(&adapter->hw))
 		e1000_phy_hw_reset(&adapter->hw);
@@ -802,6 +833,9 @@ e1000_sw_init(struct e1000_adapter *adap
 	struct e1000_hw *hw = &adapter->hw;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
+#ifdef CONFIG_E1000_NAPI
+	int i;
+#endif
 
 	/* PCI config space info */
 
@@ -859,14 +893,71 @@ e1000_sw_init(struct e1000_adapter *adap
 		hw->master_slave = E1000_MASTER_SLAVE;
 	}
 
+	adapter->num_queues = 1;
+
+	if (e1000_alloc_queues(adapter)) {
+		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
+		return -ENOMEM;
+	}
+
+#ifdef CONFIG_E1000_NAPI
+	for (i = 0; i < adapter->num_queues; i++) {
+		adapter->polling_netdev[i].priv = adapter;
+		adapter->polling_netdev[i].poll = &e1000_clean;
+		adapter->polling_netdev[i].weight = 64;
+		dev_hold(&adapter->polling_netdev[i]);
+		set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
+	}
+#endif
 	atomic_set(&adapter->irq_sem, 1);
 	spin_lock_init(&adapter->stats_lock);
-	spin_lock_init(&adapter->tx_lock);
 
 	return 0;
 }
 
 /**
+ * e1000_alloc_queues - Allocate memory for all rings
+ * @adapter: board private structure to initialize
+ *
+ * We allocate one ring per queue at run-time since we don't know the
+ * number of queues at compile-time.  The polling_netdev array is
+ * intended for Multiqueue, but should work fine with a single queue.
+ **/
+
+static int __devinit
+e1000_alloc_queues(struct e1000_adapter *adapter)
+{
+	int size;
+
+	size = sizeof(struct e1000_tx_ring) * adapter->num_queues;
+	adapter->tx_ring = kmalloc(size, GFP_KERNEL);
+	if (!adapter->tx_ring)
+		return -ENOMEM;
+	memset(adapter->tx_ring, 0, size);
+
+	size = sizeof(struct e1000_rx_ring) * adapter->num_queues;
+	adapter->rx_ring = kmalloc(size, GFP_KERNEL);
+	if (!adapter->rx_ring) {
+		kfree(adapter->tx_ring);
+		return -ENOMEM;
+	}
+	memset(adapter->rx_ring, 0, size);
+
+#ifdef CONFIG_E1000_NAPI
+	size = sizeof(struct net_device) * adapter->num_queues;
+	adapter->polling_netdev = kmalloc(size, GFP_KERNEL);
+	if (!adapter->polling_netdev) {
+		kfree(adapter->tx_ring);
+		kfree(adapter->rx_ring);
+		return -ENOMEM;
+	}
+	memset(adapter->polling_netdev, 0, size);
+#endif
+
+	return E1000_SUCCESS;
+}
+
+/**
  * e1000_open - Called when a network interface is made active
  * @netdev: network interface device structure
  *
@@ -887,12 +978,12 @@ e1000_open(struct net_device *netdev)
 
 	/* allocate transmit descriptors */
 
-	if((err = e1000_setup_tx_resources(adapter)))
+	if ((err = e1000_setup_all_tx_resources(adapter)))
 		goto err_setup_tx;
 
 	/* allocate receive descriptors */
 
-	if((err = e1000_setup_rx_resources(adapter)))
+	if ((err = e1000_setup_all_rx_resources(adapter)))
 		goto err_setup_rx;
 
 	if((err = e1000_up(adapter)))
@@ -906,9 +997,9 @@ e1000_open(struct net_device *netdev)
 	return E1000_SUCCESS;
 
 err_up:
-	e1000_free_rx_resources(adapter);
+	e1000_free_all_rx_resources(adapter);
 err_setup_rx:
-	e1000_free_tx_resources(adapter);
+	e1000_free_all_tx_resources(adapter);
 err_setup_tx:
 	e1000_reset(adapter);
 
@@ -934,8 +1025,8 @@ e1000_close(struct net_device *netdev)
 
 	e1000_down(adapter);
 
-	e1000_free_tx_resources(adapter);
-	e1000_free_rx_resources(adapter);
+	e1000_free_all_tx_resources(adapter);
+	e1000_free_all_rx_resources(adapter);
 
 	if((adapter->hw.mng_cookie.status &
 			  E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) {
@@ -970,14 +1061,15 @@ e1000_check_64k_bound(struct e1000_adapt
 /**
  * e1000_setup_tx_resources - allocate Tx resources (Descriptors)
  * @adapter: board private structure
+ * @txdr:    tx descriptor ring (for a specific queue) to setup
  *
  * Return 0 on success, negative on failure
  **/
 
 int
-e1000_setup_tx_resources(struct e1000_adapter *adapter)
+e1000_setup_tx_resources(struct e1000_adapter *adapter,
+                         struct e1000_tx_ring *txdr)
 {
-	struct e1000_desc_ring *txdr = &adapter->tx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int size;
 
@@ -1042,6 +1134,35 @@ setup_tx_desc_die:
 }
 
 /**
+ * e1000_setup_all_tx_resources - wrapper to allocate Tx resources
+ * 				  (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not).  It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+int
+e1000_setup_all_tx_resources(struct e1000_adapter *adapter)
+{
+	int i, err = 0;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]);
+		if (err) {
+			DPRINTK(PROBE, ERR,
+				"Allocation for Tx Queue %u failed\n", i);
+			break;
+		}
+	}
+
+	return err;
+}
+
+/**
  * e1000_configure_tx - Configure 8254x Transmit Unit after Reset
  * @adapter: board private structure
  *
@@ -1051,23 +1172,28 @@ setup_tx_desc_die:
 static void
 e1000_configure_tx(struct e1000_adapter *adapter)
 {
-	uint64_t tdba = adapter->tx_ring.dma;
-	uint32_t tdlen = adapter->tx_ring.count * sizeof(struct e1000_tx_desc);
-	uint32_t tctl, tipg;
-
-	E1000_WRITE_REG(&adapter->hw, TDBAL, (tdba & 0x00000000ffffffffULL));
-	E1000_WRITE_REG(&adapter->hw, TDBAH, (tdba >> 32));
-
-	E1000_WRITE_REG(&adapter->hw, TDLEN, tdlen);
+	uint64_t tdba;
+	struct e1000_hw *hw = &adapter->hw;
+	uint32_t tdlen, tctl, tipg, tarc;
 
 	/* Setup the HW Tx Head and Tail descriptor pointers */
 
 	E1000_WRITE_REG(&adapter->hw, TDH, 0);
 	E1000_WRITE_REG(&adapter->hw, TDT, 0);
+		tdba = adapter->tx_ring[0].dma;
+		tdlen = adapter->tx_ring[0].count *
+			sizeof(struct e1000_tx_desc);
+		E1000_WRITE_REG(hw, TDBAL, (tdba & 0x00000000ffffffffULL));
+		E1000_WRITE_REG(hw, TDBAH, (tdba >> 32));
+		E1000_WRITE_REG(hw, TDLEN, tdlen);
+		E1000_WRITE_REG(hw, TDH, 0);
+		E1000_WRITE_REG(hw, TDT, 0);
+		adapter->tx_ring[0].tdh = E1000_TDH;
+		adapter->tx_ring[0].tdt = E1000_TDT;
 
 	/* Set the default values for the Tx Inter Packet Gap timer */
 
-	switch (adapter->hw.mac_type) {
+	switch (hw->mac_type) {
 	case e1000_82542_rev2_0:
 	case e1000_82542_rev2_1:
 		tipg = DEFAULT_82542_TIPG_IPGT;
@@ -1075,67 +1201,68 @@ e1000_configure_tx(struct e1000_adapter 
 		tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
 		break;
 	default:
-		if(adapter->hw.media_type == e1000_media_type_fiber ||
-		   adapter->hw.media_type == e1000_media_type_internal_serdes)
+		if (hw->media_type == e1000_media_type_fiber ||
+		    hw->media_type == e1000_media_type_internal_serdes)
 			tipg = DEFAULT_82543_TIPG_IPGT_FIBER;
 		else
 			tipg = DEFAULT_82543_TIPG_IPGT_COPPER;
 		tipg |= DEFAULT_82543_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT;
 		tipg |= DEFAULT_82543_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT;
 	}
-	E1000_WRITE_REG(&adapter->hw, TIPG, tipg);
+	E1000_WRITE_REG(hw, TIPG, tipg);
 
 	/* Set the Tx Interrupt Delay register */
 
-	E1000_WRITE_REG(&adapter->hw, TIDV, adapter->tx_int_delay);
-	if(adapter->hw.mac_type >= e1000_82540)
-		E1000_WRITE_REG(&adapter->hw, TADV, adapter->tx_abs_int_delay);
+	E1000_WRITE_REG(hw, TIDV, adapter->tx_int_delay);
+	if (hw->mac_type >= e1000_82540)
+		E1000_WRITE_REG(hw, TADV, adapter->tx_abs_int_delay);
 
 	/* Program the Transmit Control Register */
 
-	tctl = E1000_READ_REG(&adapter->hw, TCTL);
+	tctl = E1000_READ_REG(hw, TCTL);
 
 	tctl &= ~E1000_TCTL_CT;
 	tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
 		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
 
-	E1000_WRITE_REG(&adapter->hw, TCTL, tctl);
+	E1000_WRITE_REG(hw, TCTL, tctl);
 
-	e1000_config_collision_dist(&adapter->hw);
+	e1000_config_collision_dist(hw);
 
 	/* Setup Transmit Descriptor Settings for eop descriptor */
 	adapter->txd_cmd = E1000_TXD_CMD_IDE | E1000_TXD_CMD_EOP |
 		E1000_TXD_CMD_IFCS;
 
-	if(adapter->hw.mac_type < e1000_82543)
+	if (hw->mac_type < e1000_82543)
 		adapter->txd_cmd |= E1000_TXD_CMD_RPS;
 	else
 		adapter->txd_cmd |= E1000_TXD_CMD_RS;
 
 	/* Cache if we're 82544 running in PCI-X because we'll
 	 * need this to apply a workaround later in the send path. */
-	if(adapter->hw.mac_type == e1000_82544 &&
-	   adapter->hw.bus_type == e1000_bus_type_pcix)
+	if (hw->mac_type == e1000_82544 &&
+	    hw->bus_type == e1000_bus_type_pcix)
 		adapter->pcix_82544 = 1;
 }
 
 /**
  * e1000_setup_rx_resources - allocate Rx resources (Descriptors)
  * @adapter: board private structure
+ * @rxdr:    rx descriptor ring (for a specific queue) to setup
  *
  * Returns 0 on success, negative on failure
  **/
 
 int
-e1000_setup_rx_resources(struct e1000_adapter *adapter)
+e1000_setup_rx_resources(struct e1000_adapter *adapter,
+                         struct e1000_rx_ring *rxdr)
 {
-	struct e1000_desc_ring *rxdr = &adapter->rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 	int size, desc_len;
 
 	size = sizeof(struct e1000_buffer) * rxdr->count;
 	rxdr->buffer_info = vmalloc(size);
-	if(!rxdr->buffer_info) {
+	if (!rxdr->buffer_info) {
 		DPRINTK(PROBE, ERR,
 		"Unable to allocate memory for the receive descriptor ring\n");
 		return -ENOMEM;
@@ -1175,13 +1302,13 @@ e1000_setup_rx_resources(struct e1000_ad
 
 	rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
 
-	if(!rxdr->desc) {
+	if (!rxdr->desc) {
+		DPRINTK(PROBE, ERR,
+		"Unable to allocate memory for the receive descriptor ring\n");
 setup_rx_desc_die:
 		vfree(rxdr->buffer_info);
 		kfree(rxdr->ps_page);
 		kfree(rxdr->ps_page_dma);
-		DPRINTK(PROBE, ERR,
-		"Unable to allocate memory for the receive descriptor ring\n");
 		return -ENOMEM;
 	}
 
@@ -1193,9 +1320,12 @@ setup_rx_desc_die:
 				     "at %p\n", rxdr->size, rxdr->desc);
 		/* Try again, without freeing the previous */
 		rxdr->desc = pci_alloc_consistent(pdev, rxdr->size, &rxdr->dma);
-		if(!rxdr->desc) {
 		/* Failed allocation, critical failure */
+		if (!rxdr->desc) {
 			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
+			DPRINTK(PROBE, ERR,
+				"Unable to allocate memory "
+				"for the receive descriptor ring\n");
 			goto setup_rx_desc_die;
 		}
 
@@ -1207,10 +1337,7 @@ setup_rx_desc_die:
 			DPRINTK(PROBE, ERR,
 				"Unable to allocate aligned memory "
 				"for the receive descriptor ring\n");
-			vfree(rxdr->buffer_info);
-			kfree(rxdr->ps_page);
-			kfree(rxdr->ps_page_dma);
-			return -ENOMEM;
+			goto setup_rx_desc_die;
 		} else {
 			/* Free old allocation, new allocation was successful */
 			pci_free_consistent(pdev, rxdr->size, olddesc, olddma);
@@ -1225,6 +1352,35 @@ setup_rx_desc_die:
 }
 
 /**
+ * e1000_setup_all_rx_resources - wrapper to allocate Rx resources
+ * 				  (Descriptors) for all queues
+ * @adapter: board private structure
+ *
+ * If this function returns with an error, then it's possible one or
+ * more of the rings is populated (while the rest are not).  It is the
+ * callers duty to clean those orphaned rings.
+ *
+ * Return 0 on success, negative on failure
+ **/
+
+int
+e1000_setup_all_rx_resources(struct e1000_adapter *adapter)
+{
+	int i, err = 0;
+
+	for (i = 0; i < adapter->num_queues; i++) {
+		err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]);
+		if (err) {
+			DPRINTK(PROBE, ERR,
+				"Allocation for Rx Queue %u failed\n", i);
+			break;
+		}
+	}
+
+	return err;
+}
+
+/**
  * e1000_setup_rctl - configure the receive control registers
  * @adapter: Board private structure
  **/
@@ -1326,47 +1482,55 @@ e1000_setup_rctl(struct e1000_adapter *a
 static void
 e1000_configure_rx(struct e1000_adapter *adapter)
 {
-	uint64_t rdba = adapter->rx_ring.dma;
-	uint32_t rdlen, rctl, rxcsum;
+	uint64_t rdba;
+	struct e1000_hw *hw = &adapter->hw;
+	uint32_t rdlen, rctl, rxcsum, ctrl_ext;
+#ifdef CONFIG_E1000_MQ
+	uint32_t reta, mrqc;
+	int i;
+#endif
 
 	if(adapter->rx_ps) {
-		rdlen = adapter->rx_ring.count *
+		rdlen = adapter->rx_ring[0].count *
 			sizeof(union e1000_rx_desc_packet_split);
 		adapter->clean_rx = e1000_clean_rx_irq_ps;
 		adapter->alloc_rx_buf = e1000_alloc_rx_buffers_ps;
 	} else {
-		rdlen = adapter->rx_ring.count * sizeof(struct e1000_rx_desc);
+		rdlen = adapter->rx_ring[0].count *
+			sizeof(struct e1000_rx_desc);
 		adapter->clean_rx = e1000_clean_rx_irq;
 		adapter->alloc_rx_buf = e1000_alloc_rx_buffers;
 	}
 
 	/* disable receives while setting up the descriptors */
-	rctl = E1000_READ_REG(&adapter->hw, RCTL);
-	E1000_WRITE_REG(&adapter->hw, RCTL, rctl & ~E1000_RCTL_EN);
+	rctl = E1000_READ_REG(hw, RCTL);
+	E1000_WRITE_REG(hw, RCTL, rctl & ~E1000_RCTL_EN);
 
 	/* set the Receive Delay Timer Register */
-	E1000_WRITE_REG(&adapter->hw, RDTR, adapter->rx_int_delay);
+	E1000_WRITE_REG(hw, RDTR, adapter->rx_int_delay);
 
-	if(adapter->hw.mac_type >= e1000_82540) {
-		E1000_WRITE_REG(&adapter->hw, RADV, adapter->rx_abs_int_delay);
+	if (hw->mac_type >= e1000_82540) {
+		E1000_WRITE_REG(hw, RADV, adapter->rx_abs_int_delay);
 		if(adapter->itr > 1)
-			E1000_WRITE_REG(&adapter->hw, ITR,
+			E1000_WRITE_REG(hw, ITR,
 				1000000000 / (adapter->itr * 256));
 	}
 
-	/* Setup the Base and Length of the Rx Descriptor Ring */
-	E1000_WRITE_REG(&adapter->hw, RDBAL, (rdba & 0x00000000ffffffffULL));
-	E1000_WRITE_REG(&adapter->hw, RDBAH, (rdba >> 32));
-
-	E1000_WRITE_REG(&adapter->hw, RDLEN, rdlen);
-
-	/* Setup the HW Rx Head and Tail Descriptor Pointers */
-	E1000_WRITE_REG(&adapter->hw, RDH, 0);
-	E1000_WRITE_REG(&adapter->hw, RDT, 0);
+	/* Setup the HW Rx Head and Tail Descriptor Pointers and
+	 * the Base and Length of the Rx Descriptor Ring */
+		rdba = adapter->rx_ring[0].dma;
+		E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
+		E1000_WRITE_REG(hw, RDBAH, (rdba >> 32));
+		E1000_WRITE_REG(hw, RDLEN, rdlen);
+		E1000_WRITE_REG(hw, RDH, 0);
+		E1000_WRITE_REG(hw, RDT, 0);
+		adapter->rx_ring[0].rdh = E1000_RDH;
+		adapter->rx_ring[0].rdt = E1000_RDT;
+		break;
 
 	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
-	if(adapter->hw.mac_type >= e1000_82543) {
-		rxcsum = E1000_READ_REG(&adapter->hw, RXCSUM);
+	if (hw->mac_type >= e1000_82543) {
+		rxcsum = E1000_READ_REG(hw, RXCSUM);
 		if(adapter->rx_csum == TRUE) {
 			rxcsum |= E1000_RXCSUM_TUOFL;
 
@@ -1380,37 +1544,54 @@ e1000_configure_rx(struct e1000_adapter 
 			rxcsum &= ~E1000_RXCSUM_TUOFL;
 			/* don't need to clear IPPCSE as it defaults to 0 */
 		}
-		E1000_WRITE_REG(&adapter->hw, RXCSUM, rxcsum);
+		E1000_WRITE_REG(hw, RXCSUM, rxcsum);
 	}
 
-	if (adapter->hw.mac_type == e1000_82573)
-		E1000_WRITE_REG(&adapter->hw, ERT, 0x0100);
+	if (hw->mac_type == e1000_82573)
+		E1000_WRITE_REG(hw, ERT, 0x0100);
 
 	/* Enable Receives */
-	E1000_WRITE_REG(&adapter->hw, RCTL, rctl);
+	E1000_WRITE_REG(hw, RCTL, rctl);
 }
 
 /**
- * e1000_free_tx_resources - Free Tx Resources
+ * e1000_free_tx_resources - Free Tx Resources per Queue
  * @adapter: board private structure
+ * @tx_ring: Tx descriptor ring for a specific queue
  *
  * Free all transmit software resources
  **/
 
 void
-e1000_free_tx_resources(struct e1000_adapter *adapter)
+e1000_free_tx_resources(struct e1000_adapter *adapter,
+                        struct e1000_tx_ring *tx_ring)
 {
 	struct pci_dev *pdev = adapter->pdev;
 
-	e1000_clean_tx_ring(adapter);
+	e1000_clean_tx_ring(adapter, tx_ring);
 
-	vfree(adapter->tx_ring.buffer_info);
-	adapter->tx_ring.buffer_info = NULL;
+	vfree(tx_ring->buffer_info);
+	tx_ring->buffer_info = NULL;
+
+	pci_free_consistent(pdev, tx_ring->size, tx_ring->desc, tx_ring->dma);
+
+	tx_ring->desc = NULL;
+}
+
+/**
+ * e1000_free_all_tx_resources - Free Tx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all transmit software resources
+ **/
 
-	pci_free_consistent(pdev, adapter->tx_ring.size,
-	                    adapter->tx_ring.desc, adapter->tx_ring.dma);
+void
+e1000_free_all_tx_resources(struct e1000_adapter *adapter)
+{
+	int i;
 
-	adapter->tx_ring.desc = NULL;
+	for (i = 0; i < adapter->num_queues; i++)
+		e1000_free_tx_resources(adapter, &adapter->tx_ring[i]);
 }
 
 static inline void
@@ -1433,21 +1614,22 @@ e1000_unmap_and_free_tx_resource(struct 
 /**
  * e1000_clean_tx_ring - Free Tx Buffers
  * @adapter: board private structure
+ * @tx_ring: ring to be cleaned
  **/
 
 static void
-e1000_clean_tx_ring(struct e1000_adapter *adapter)
+e1000_clean_tx_ring(struct e1000_adapter *adapter,
+                    struct e1000_tx_ring *tx_ring)
 {
-	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 	struct e1000_buffer *buffer_info;
 	unsigned long size;
 	unsigned int i;
 
 	/* Free all the Tx ring sk_buffs */
 
-	if (likely(adapter->previous_buffer_info.skb != NULL)) {
+	if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
 		e1000_unmap_and_free_tx_resource(adapter,
-				&adapter->previous_buffer_info);
+				&tx_ring->previous_buffer_info);
 	}
 
 	for(i = 0; i < tx_ring->count; i++) {
@@ -1465,24 +1647,39 @@ e1000_clean_tx_ring(struct e1000_adapter
 	tx_ring->next_to_use = 0;
 	tx_ring->next_to_clean = 0;
 
-	E1000_WRITE_REG(&adapter->hw, TDH, 0);
-	E1000_WRITE_REG(&adapter->hw, TDT, 0);
+	writel(0, adapter->hw.hw_addr + tx_ring->tdh);
+	writel(0, adapter->hw.hw_addr + tx_ring->tdt);
+}
+
+/**
+ * e1000_clean_all_tx_rings - Free Tx Buffers for all queues
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_all_tx_rings(struct e1000_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]);
 }
 
 /**
  * e1000_free_rx_resources - Free Rx Resources
  * @adapter: board private structure
+ * @rx_ring: ring to clean the resources from
  *
  * Free all receive software resources
  **/
 
 void
-e1000_free_rx_resources(struct e1000_adapter *adapter)
+e1000_free_rx_resources(struct e1000_adapter *adapter,
+                        struct e1000_rx_ring *rx_ring)
 {
-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
 	struct pci_dev *pdev = adapter->pdev;
 
-	e1000_clean_rx_ring(adapter);
+	e1000_clean_rx_ring(adapter, rx_ring);
 
 	vfree(rx_ring->buffer_info);
 	rx_ring->buffer_info = NULL;
@@ -1497,14 +1694,31 @@ e1000_free_rx_resources(struct e1000_ada
 }
 
 /**
- * e1000_clean_rx_ring - Free Rx Buffers
+ * e1000_free_all_rx_resources - Free Rx Resources for All Queues
+ * @adapter: board private structure
+ *
+ * Free all receive software resources
+ **/
+
+void
+e1000_free_all_rx_resources(struct e1000_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		e1000_free_rx_resources(adapter, &adapter->rx_ring[i]);
+}
+
+/**
+ * e1000_clean_rx_ring - Free Rx Buffers per Queue
  * @adapter: board private structure
+ * @rx_ring: ring to free buffers from
  **/
 
 static void
-e1000_clean_rx_ring(struct e1000_adapter *adapter)
+e1000_clean_rx_ring(struct e1000_adapter *adapter,
+                    struct e1000_rx_ring *rx_ring)
 {
-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
 	struct e1000_buffer *buffer_info;
 	struct e1000_ps_page *ps_page;
 	struct e1000_ps_page_dma *ps_page_dma;
@@ -1553,8 +1767,22 @@ e1000_clean_rx_ring(struct e1000_adapter
 	rx_ring->next_to_clean = 0;
 	rx_ring->next_to_use = 0;
 
-	E1000_WRITE_REG(&adapter->hw, RDH, 0);
-	E1000_WRITE_REG(&adapter->hw, RDT, 0);
+	writel(0, adapter->hw.hw_addr + rx_ring->rdh);
+	writel(0, adapter->hw.hw_addr + rx_ring->rdt);
+}
+
+/**
+ * e1000_clean_all_rx_rings - Free Rx Buffers for all queues
+ * @adapter: board private structure
+ **/
+
+static void
+e1000_clean_all_rx_rings(struct e1000_adapter *adapter)
+{
+	int i;
+
+	for (i = 0; i < adapter->num_queues; i++)
+		e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]);
 }
 
 /* The 82542 2.0 (revision 2) needs to have the receive unit in reset
@@ -1575,7 +1803,7 @@ e1000_enter_82542_rst(struct e1000_adapt
 	mdelay(5);
 
 	if(netif_running(netdev))
-		e1000_clean_rx_ring(adapter);
+		e1000_clean_all_rx_rings(adapter);
 }
 
 static void
@@ -1595,7 +1823,7 @@ e1000_leave_82542_rst(struct e1000_adapt
 
 	if(netif_running(netdev)) {
 		e1000_configure_rx(adapter);
-		e1000_alloc_rx_buffers(adapter);
+		e1000_alloc_rx_buffers(adapter, &adapter->rx_ring[0]);
 	}
 }
 
@@ -1664,12 +1892,10 @@ e1000_set_multi(struct net_device *netde
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	struct dev_mc_list *mc_ptr;
-	unsigned long flags;
 	uint32_t rctl;
 	uint32_t hash_value;
 	int i, rar_entries = E1000_RAR_ENTRIES;
 
-	spin_lock_irqsave(&adapter->tx_lock, flags);
 	/* reserve RAR[14] for LAA over-write work-around */
 	if (adapter->hw.mac_type == e1000_82571)
 		rar_entries--;
@@ -1725,8 +1951,6 @@ e1000_set_multi(struct net_device *netde
 
 	if(hw->mac_type == e1000_82542_rev2_0)
 		e1000_leave_82542_rst(adapter);
-
-	spin_unlock_irqrestore(&adapter->tx_lock, flags);
 }
 
 /* Need to wait a few seconds after link up to get diagnostic information from
@@ -1798,7 +2022,7 @@ static void
 e1000_watchdog_task(struct e1000_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
-	struct e1000_desc_ring *txdr = &adapter->tx_ring;
+	struct e1000_tx_ring *txdr = &adapter->tx_ring[0];
 	uint32_t link;
 
 	e1000_check_for_link(&adapter->hw);
@@ -1857,8 +2081,8 @@ e1000_watchdog_task(struct e1000_adapter
 
 	e1000_update_adaptive(&adapter->hw);
 
-	if(!netif_carrier_ok(netdev)) {
-		if(E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
+	if (adapter->num_queues == 1 && !netif_carrier_ok(netdev)) {
+		if (E1000_DESC_UNUSED(txdr) + 1 < txdr->count) {
 			/* We've lost link, so the controller stops DMA,
 			 * but we've got queued Tx work that's never going
 			 * to get done, so reset controller to flush Tx.
@@ -1903,7 +2127,8 @@ e1000_watchdog_task(struct e1000_adapter
 #define E1000_TX_FLAGS_VLAN_SHIFT	16
 
 static inline int
-e1000_tso(struct e1000_adapter *adapter, struct sk_buff *skb)
+e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+          struct sk_buff *skb)
 {
 #ifdef NETIF_F_TSO
 	struct e1000_context_desc *context_desc;
@@ -1954,8 +2179,8 @@ e1000_tso(struct e1000_adapter *adapter,
 		cmd_length |= (E1000_TXD_CMD_DEXT | E1000_TXD_CMD_TSE |
 			       E1000_TXD_CMD_TCP | (skb->len - (hdr_len)));
 
-		i = adapter->tx_ring.next_to_use;
-		context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
+		i = tx_ring->next_to_use;
+		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
 
 		context_desc->lower_setup.ip_fields.ipcss  = ipcss;
 		context_desc->lower_setup.ip_fields.ipcso  = ipcso;
@@ -1967,8 +2192,8 @@ e1000_tso(struct e1000_adapter *adapter,
 		context_desc->tcp_seg_setup.fields.hdr_len = hdr_len;
 		context_desc->cmd_and_length = cpu_to_le32(cmd_length);
 
-		if(++i == adapter->tx_ring.count) i = 0;
-		adapter->tx_ring.next_to_use = i;
+		if (++i == tx_ring->count) i = 0;
+		tx_ring->next_to_use = i;
 
 		return 1;
 	}
@@ -1978,7 +2203,8 @@ e1000_tso(struct e1000_adapter *adapter,
 }
 
 static inline boolean_t
-e1000_tx_csum(struct e1000_adapter *adapter, struct sk_buff *skb)
+e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+              struct sk_buff *skb)
 {
 	struct e1000_context_desc *context_desc;
 	unsigned int i;
@@ -1987,8 +2213,8 @@ e1000_tx_csum(struct e1000_adapter *adap
 	if(likely(skb->ip_summed == CHECKSUM_HW)) {
 		css = skb->h.raw - skb->data;
 
-		i = adapter->tx_ring.next_to_use;
-		context_desc = E1000_CONTEXT_DESC(adapter->tx_ring, i);
+		i = tx_ring->next_to_use;
+		context_desc = E1000_CONTEXT_DESC(*tx_ring, i);
 
 		context_desc->upper_setup.tcp_fields.tucss = css;
 		context_desc->upper_setup.tcp_fields.tucso = css + skb->csum;
@@ -1996,8 +2222,8 @@ e1000_tx_csum(struct e1000_adapter *adap
 		context_desc->tcp_seg_setup.data = 0;
 		context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT);
 
-		if(unlikely(++i == adapter->tx_ring.count)) i = 0;
-		adapter->tx_ring.next_to_use = i;
+		if (unlikely(++i == tx_ring->count)) i = 0;
+		tx_ring->next_to_use = i;
 
 		return TRUE;
 	}
@@ -2009,11 +2235,10 @@ e1000_tx_csum(struct e1000_adapter *adap
 #define E1000_MAX_DATA_PER_TXD	(1<<E1000_MAX_TXD_PWR)
 
 static inline int
-e1000_tx_map(struct e1000_adapter *adapter, struct sk_buff *skb,
-	unsigned int first, unsigned int max_per_txd,
-	unsigned int nr_frags, unsigned int mss)
+e1000_tx_map(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+             struct sk_buff *skb, unsigned int first, unsigned int max_per_txd,
+             unsigned int nr_frags, unsigned int mss)
 {
-	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 	struct e1000_buffer *buffer_info;
 	unsigned int len = skb->len;
 	unsigned int offset = 0, size, count = 0, i;
@@ -2109,9 +2334,9 @@ e1000_tx_map(struct e1000_adapter *adapt
 }
 
 static inline void
-e1000_tx_queue(struct e1000_adapter *adapter, int count, int tx_flags)
+e1000_tx_queue(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring,
+               int tx_flags, int count)
 {
-	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 	struct e1000_tx_desc *tx_desc = NULL;
 	struct e1000_buffer *buffer_info;
 	uint32_t txd_upper = 0, txd_lower = E1000_TXD_CMD_IFCS;
@@ -2157,7 +2382,7 @@ e1000_tx_queue(struct e1000_adapter *ada
 	wmb();
 
 	tx_ring->next_to_use = i;
-	E1000_WRITE_REG(&adapter->hw, TDT, i);
+	writel(i, adapter->hw.hw_addr + tx_ring->tdt);
 }
 
 /**
@@ -2250,6 +2475,7 @@ static int
 e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev)
 {
 	struct e1000_adapter *adapter = netdev_priv(netdev);
+	struct e1000_tx_ring *tx_ring;
 	unsigned int first, max_per_txd = E1000_MAX_DATA_PER_TXD;
 	unsigned int max_txd_pwr = E1000_MAX_TXD_PWR;
 	unsigned int tx_flags = 0;
@@ -2262,7 +2488,8 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	unsigned int f;
 	len -= skb->data_len;
 
-	if(unlikely(skb->len <= 0)) {
+	tx_ring = adapter->tx_ring;
+	if (unlikely(skb->len <= 0)) {
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
 	}
@@ -2306,12 +2533,6 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	if(adapter->pcix_82544)
 		count += nr_frags;
 
- 	local_irq_save(flags); 
- 	if (!spin_trylock(&adapter->tx_lock)) { 
- 		/* Collision - tell upper layer to requeue */ 
- 		local_irq_restore(flags); 
- 		return NETDEV_TX_LOCKED; 
- 	} 
 #ifdef NETIF_F_TSO
 	/* TSO Workaround for 82571/2 Controllers -- if skb->data
 	 * points to just header, pull a few bytes of payload from 
@@ -2336,12 +2557,18 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	if(adapter->hw.tx_pkt_filtering && (adapter->hw.mac_type == e1000_82573) )
 		e1000_transfer_dhcp_info(adapter, skb);
 
+	local_irq_save(flags);
+	if (!spin_trylock(&tx_ring->tx_lock)) {
+		/* Collision - tell upper layer to requeue */
+		local_irq_restore(flags);
+		return NETDEV_TX_LOCKED;
+	}
 
 	/* need: count + 2 desc gap to keep tail from touching
 	 * head, otherwise try next time */
-	if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < count + 2)) {
+	if (unlikely(E1000_DESC_UNUSED(tx_ring) < count + 2)) {
 		netif_stop_queue(netdev);
-		spin_unlock_irqrestore(&adapter->tx_lock, flags);
+		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 		return NETDEV_TX_BUSY;
 	}
 
@@ -2349,7 +2576,7 @@ e1000_xmit_frame(struct sk_buff *skb, st
 		if(unlikely(e1000_82547_fifo_workaround(adapter, skb))) {
 			netif_stop_queue(netdev);
 			mod_timer(&adapter->tx_fifo_stall_timer, jiffies);
-			spin_unlock_irqrestore(&adapter->tx_lock, flags);
+			spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 			return NETDEV_TX_BUSY;
 		}
 	}
@@ -2359,37 +2586,37 @@ e1000_xmit_frame(struct sk_buff *skb, st
 		tx_flags |= (vlan_tx_tag_get(skb) << E1000_TX_FLAGS_VLAN_SHIFT);
 	}
 
-	first = adapter->tx_ring.next_to_use;
+	first = tx_ring->next_to_use;
 	
-	tso = e1000_tso(adapter, skb);
+	tso = e1000_tso(adapter, tx_ring, skb);
 	if (tso < 0) {
 		dev_kfree_skb_any(skb);
-		spin_unlock_irqrestore(&adapter->tx_lock, flags);
+		spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 		return NETDEV_TX_OK;
 	}
 
 	if (likely(tso))
 		tx_flags |= E1000_TX_FLAGS_TSO;
-	else if(likely(e1000_tx_csum(adapter, skb)))
+	else if (likely(e1000_tx_csum(adapter, tx_ring, skb)))
 		tx_flags |= E1000_TX_FLAGS_CSUM;
 
 	/* Old method was to assume IPv4 packet by default if TSO was enabled.
 	 * 82571 hardware supports TSO capabilities for IPv6 as well...
 	 * no longer assume, we must. */
-	if(likely(skb->protocol == ntohs(ETH_P_IP)))
+	if (likely(skb->protocol == ntohs(ETH_P_IP)))
 		tx_flags |= E1000_TX_FLAGS_IPV4;
 
-	e1000_tx_queue(adapter,
-		e1000_tx_map(adapter, skb, first, max_per_txd, nr_frags, mss),
-		tx_flags);
+	e1000_tx_queue(adapter, tx_ring, tx_flags,
+	               e1000_tx_map(adapter, tx_ring, skb, first,
+	                            max_per_txd, nr_frags, mss));
 
 	netdev->trans_start = jiffies;
 
 	/* Make sure there is space in the ring for the next send. */
-	if(unlikely(E1000_DESC_UNUSED(&adapter->tx_ring) < MAX_SKB_FRAGS + 2))
+	if (unlikely(E1000_DESC_UNUSED(tx_ring) < MAX_SKB_FRAGS + 2))
 		netif_stop_queue(netdev);
 
-	spin_unlock_irqrestore(&adapter->tx_lock, flags);
+	spin_unlock_irqrestore(&tx_ring->tx_lock, flags);
 	return NETDEV_TX_OK;
 }
 
@@ -2666,9 +2893,7 @@ e1000_intr(int irq, void *data, struct p
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint32_t icr = E1000_READ_REG(hw, ICR);
-#ifndef CONFIG_E1000_NAPI
-	unsigned int i;
-#endif
+	int i;
 
 	if(unlikely(!icr))
 		return IRQ_NONE;  /* Not our interrupt */
@@ -2679,17 +2904,15 @@ e1000_intr(int irq, void *data, struct p
 	}
 
 #ifdef CONFIG_E1000_NAPI
-	if(likely(netif_rx_schedule_prep(netdev))) {
-
-		/* Disable interrupts and register for poll. The flush 
-		  of the posted write is intentionally left out.
-		*/
-
-		atomic_inc(&adapter->irq_sem);
-		E1000_WRITE_REG(hw, IMC, ~0);
-		__netif_rx_schedule(netdev);
+	atomic_inc(&adapter->irq_sem);
+	E1000_WRITE_REG(hw, IMC, ~0);
+	E1000_WRITE_FLUSH(hw);
 	}
 #else
+	if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0])))
+		__netif_rx_schedule(&adapter->polling_netdev[0]);
+	else
+		e1000_irq_enable(adapter);
 	/* Writing IMC and IMS is needed for 82547.
 	   Due to Hub Link bus being occupied, an interrupt
 	   de-assertion message is not able to be sent.
@@ -2706,12 +2929,13 @@ e1000_intr(int irq, void *data, struct p
 	}
 
 	for(i = 0; i < E1000_MAX_INTR; i++)
-		if(unlikely(!adapter->clean_rx(adapter) &
-		   !e1000_clean_tx_irq(adapter)))
+		if(unlikely(!adapter->clean_rx(adapter, adapter->rx_ring) &
+		   !e1000_clean_tx_irq(adapter, adapter->tx_ring)))
 			break;
 
 	if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
 		e1000_irq_enable(adapter);
+
 #endif
 
 	return IRQ_HANDLED;
@@ -2724,22 +2948,37 @@ e1000_intr(int irq, void *data, struct p
  **/
 
 static int
-e1000_clean(struct net_device *netdev, int *budget)
+e1000_clean(struct net_device *poll_dev, int *budget)
 {
-	struct e1000_adapter *adapter = netdev_priv(netdev);
-	int work_to_do = min(*budget, netdev->quota);
-	int tx_cleaned;
-	int work_done = 0;
+	struct e1000_adapter *adapter;
+	int work_to_do = min(*budget, poll_dev->quota);
+	int tx_cleaned, i = 0, work_done = 0;
+
+	/* Must NOT use netdev_priv macro here. */
+	adapter = poll_dev->priv;
+
+	/* Keep link state information with original netdev */
+	if (!netif_carrier_ok(adapter->netdev))
+		goto quit_polling;
 
-	tx_cleaned = e1000_clean_tx_irq(adapter);
-	adapter->clean_rx(adapter, &work_done, work_to_do);
+	while (poll_dev != &adapter->polling_netdev[i]) {
+		i++;
+		if (unlikely(i == adapter->num_queues))
+			BUG();
+	}
+
+	tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]);
+	adapter->clean_rx(adapter, &adapter->rx_ring[i],
+	                  &work_done, work_to_do);
 
 	*budget -= work_done;
-	netdev->quota -= work_done;
+	poll_dev->quota -= work_done;
 	
-	if ((!tx_cleaned && (work_done == 0)) || !netif_running(netdev)) {
 	/* If no Tx and not enough Rx work done, exit the polling mode */
-		netif_rx_complete(netdev);
+	if((!tx_cleaned && (work_done == 0)) ||
+	   !netif_running(adapter->netdev)) {
+quit_polling:
+		netif_rx_complete(poll_dev);
 		e1000_irq_enable(adapter);
 		return 0;
 	}
@@ -2754,9 +2993,9 @@ e1000_clean(struct net_device *netdev, i
  **/
 
 static boolean_t
-e1000_clean_tx_irq(struct e1000_adapter *adapter)
+e1000_clean_tx_irq(struct e1000_adapter *adapter,
+                   struct e1000_tx_ring *tx_ring)
 {
-	struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
 	struct net_device *netdev = adapter->netdev;
 	struct e1000_tx_desc *tx_desc, *eop_desc;
 	struct e1000_buffer *buffer_info;
@@ -2767,12 +3006,12 @@ e1000_clean_tx_irq(struct e1000_adapter 
 	eop = tx_ring->buffer_info[i].next_to_watch;
 	eop_desc = E1000_TX_DESC(*tx_ring, eop);
 
-	while(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
+	while (eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) {
 		/* Premature writeback of Tx descriptors clear (free buffers
 		 * and unmap pci_mapping) previous_buffer_info */
-		if (likely(adapter->previous_buffer_info.skb != NULL)) {
+		if (likely(tx_ring->previous_buffer_info.skb != NULL)) {
 			e1000_unmap_and_free_tx_resource(adapter,
-					&adapter->previous_buffer_info);
+					&tx_ring->previous_buffer_info);
 		}
 
 		for(cleaned = FALSE; !cleaned; ) {
@@ -2788,7 +3027,7 @@ e1000_clean_tx_irq(struct e1000_adapter 
 #ifdef NETIF_F_TSO
 			} else {
 				if (cleaned) {
-					memcpy(&adapter->previous_buffer_info,
+					memcpy(&tx_ring->previous_buffer_info,
 					       buffer_info,
 					       sizeof(struct e1000_buffer));
 					memset(buffer_info, 0,
@@ -2806,6 +3045,8 @@ e1000_clean_tx_irq(struct e1000_adapter 
 
 			if(unlikely(++i == tx_ring->count)) i = 0;
 		}
+
+		tx_ring->pkt++;
 		
 		eop = tx_ring->buffer_info[i].next_to_watch;
 		eop_desc = E1000_TX_DESC(*tx_ring, eop);
@@ -2813,15 +3054,15 @@ e1000_clean_tx_irq(struct e1000_adapter 
 
 	tx_ring->next_to_clean = i;
 
-	spin_lock(&adapter->tx_lock);
+	spin_lock(&tx_ring->tx_lock);
 
 	if(unlikely(cleaned && netif_queue_stopped(netdev) &&
 		    netif_carrier_ok(netdev)))
 		netif_wake_queue(netdev);
 
-	spin_unlock(&adapter->tx_lock);
-	if(adapter->detect_tx_hung) {
+	spin_unlock(&tx_ring->tx_lock);
 
+	if (adapter->detect_tx_hung) {
 		/* Detect a transmit hang in hardware, this serializes the
 		 * check with the clearing of time_stamp and movement of i */
 		adapter->detect_tx_hung = FALSE;
@@ -2845,8 +3086,8 @@ e1000_clean_tx_irq(struct e1000_adapter 
 					"  next_to_watch        <%x>\n"
 					"  jiffies              <%lx>\n"
 					"  next_to_watch.status <%x>\n",
-				E1000_READ_REG(&adapter->hw, TDH),
-				E1000_READ_REG(&adapter->hw, TDT),
+				readl(adapter->hw.hw_addr + tx_ring->tdh),
+				readl(adapter->hw.hw_addr + tx_ring->tdt),
 				tx_ring->next_to_use,
 				i,
 				(unsigned long long)tx_ring->buffer_info[i].dma,
@@ -2858,12 +3099,10 @@ e1000_clean_tx_irq(struct e1000_adapter 
 		}
 	}
 #ifdef NETIF_F_TSO
-
-	if( unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
-	    time_after(jiffies, adapter->previous_buffer_info.time_stamp + HZ)))
+	if (unlikely(!(eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
+	    time_after(jiffies, tx_ring->previous_buffer_info.time_stamp + HZ)))
 		e1000_unmap_and_free_tx_resource(
-		    adapter, &adapter->previous_buffer_info);
-
+		    adapter, &tx_ring->previous_buffer_info);
 #endif
 	return cleaned;
 }
@@ -2926,13 +3165,14 @@ e1000_rx_checksum(struct e1000_adapter *
 
 static boolean_t
 #ifdef CONFIG_E1000_NAPI
-e1000_clean_rx_irq(struct e1000_adapter *adapter, int *work_done,
-                   int work_to_do)
+e1000_clean_rx_irq(struct e1000_adapter *adapter,
+                   struct e1000_rx_ring *rx_ring,
+                   int *work_done, int work_to_do)
 #else
-e1000_clean_rx_irq(struct e1000_adapter *adapter)
+e1000_clean_rx_irq(struct e1000_adapter *adapter,
+                   struct e1000_rx_ring *rx_ring)
 #endif
 {
-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_rx_desc *rx_desc;
@@ -3018,6 +3258,7 @@ e1000_clean_rx_irq(struct e1000_adapter 
 		}
 #endif /* CONFIG_E1000_NAPI */
 		netdev->last_rx = jiffies;
+		rx_ring->pkt++;
 
 next_desc:
 		rx_desc->status = 0;
@@ -3027,7 +3268,7 @@ next_desc:
 		rx_desc = E1000_RX_DESC(*rx_ring, i);
 	}
 	rx_ring->next_to_clean = i;
-	adapter->alloc_rx_buf(adapter);
+	adapter->alloc_rx_buf(adapter, rx_ring);
 
 	return cleaned;
 }
@@ -3039,13 +3280,14 @@ next_desc:
 
 static boolean_t
 #ifdef CONFIG_E1000_NAPI
-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, int *work_done,
-                      int work_to_do)
+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+                      struct e1000_rx_ring *rx_ring,
+                      int *work_done, int work_to_do)
 #else
-e1000_clean_rx_irq_ps(struct e1000_adapter *adapter)
+e1000_clean_rx_irq_ps(struct e1000_adapter *adapter,
+                      struct e1000_rx_ring *rx_ring)
 #endif
 {
-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
 	union e1000_rx_desc_packet_split *rx_desc;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
@@ -3145,6 +3387,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
 		}
 #endif /* CONFIG_E1000_NAPI */
 		netdev->last_rx = jiffies;
+		rx_ring->pkt++;
 
 next_desc:
 		rx_desc->wb.middle.status_error &= ~0xFF;
@@ -3155,7 +3398,7 @@ next_desc:
 		staterr = le32_to_cpu(rx_desc->wb.middle.status_error);
 	}
 	rx_ring->next_to_clean = i;
-	adapter->alloc_rx_buf(adapter);
+	adapter->alloc_rx_buf(adapter, rx_ring);
 
 	return cleaned;
 }
@@ -3166,9 +3409,9 @@ next_desc:
  **/
 
 static void
-e1000_alloc_rx_buffers(struct e1000_adapter *adapter)
+e1000_alloc_rx_buffers(struct e1000_adapter *adapter,
+                       struct e1000_rx_ring *rx_ring)
 {
-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
 	struct e1000_rx_desc *rx_desc;
@@ -3252,7 +3495,7 @@ e1000_alloc_rx_buffers(struct e1000_adap
 			 * applicable for weak-ordered memory model archs,
 			 * such as IA-64). */
 			wmb();
-			E1000_WRITE_REG(&adapter->hw, RDT, i);
+			writel(i, adapter->hw.hw_addr + rx_ring->rdt);
 		}
 
 		if(unlikely(++i == rx_ring->count)) i = 0;
@@ -3268,9 +3511,9 @@ e1000_alloc_rx_buffers(struct e1000_adap
  **/
 
 static void
-e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter)
+e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter,
+                          struct e1000_rx_ring *rx_ring)
 {
-	struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
 	struct net_device *netdev = adapter->netdev;
 	struct pci_dev *pdev = adapter->pdev;
 	union e1000_rx_desc_packet_split *rx_desc;
@@ -3338,7 +3581,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_a
 			 * descriptors are 32 bytes...so we increment tail
 			 * twice as much.
 			 */
-			E1000_WRITE_REG(&adapter->hw, RDT, i<<1);
+			writel(i<<1, adapter->hw.hw_addr + rx_ring->rdt);
 		}
 
 		if(unlikely(++i == rx_ring->count)) i = 0;
diff --git a/drivers/net/e1000/e1000_param.c b/drivers/net/e1000/e1000_param.c
index 676247f..38695d5 100644
--- a/drivers/net/e1000/e1000_param.c
+++ b/drivers/net/e1000/e1000_param.c
@@ -306,7 +306,8 @@ e1000_check_options(struct e1000_adapter
 			.def  = E1000_DEFAULT_TXD,
 			.arg  = { .r = { .min = E1000_MIN_TXD }}
 		};
-		struct e1000_desc_ring *tx_ring = &adapter->tx_ring;
+		struct e1000_tx_ring *tx_ring = adapter->tx_ring;
+		int i;
 		e1000_mac_type mac_type = adapter->hw.mac_type;
 		opt.arg.r.max = mac_type < e1000_82544 ?
 			E1000_MAX_TXD : E1000_MAX_82544_TXD;
@@ -319,6 +320,8 @@ e1000_check_options(struct e1000_adapter
 		} else {
 			tx_ring->count = opt.def;
 		}
+		for (i = 0; i < adapter->num_queues; i++)
+			tx_ring[i].count = tx_ring->count;
 	}
 	{ /* Receive Descriptor Count */
 		struct e1000_option opt = {
@@ -329,7 +332,8 @@ e1000_check_options(struct e1000_adapter
 			.def  = E1000_DEFAULT_RXD,
 			.arg  = { .r = { .min = E1000_MIN_RXD }}
 		};
-		struct e1000_desc_ring *rx_ring = &adapter->rx_ring;
+		struct e1000_rx_ring *rx_ring = adapter->rx_ring;
+		int i;
 		e1000_mac_type mac_type = adapter->hw.mac_type;
 		opt.arg.r.max = mac_type < e1000_82544 ? E1000_MAX_RXD :
 			E1000_MAX_82544_RXD;
@@ -342,6 +346,8 @@ e1000_check_options(struct e1000_adapter
 		} else {
 			rx_ring->count = opt.def;
 		}
+		for (i = 0; i < adapter->num_queues; i++)
+			rx_ring[i].count = rx_ring->count;
 	}
 	{ /* Checksum Offload Enable/Disable */
 		struct e1000_option opt = {
---
0.99.8.GIT


--- NEW FILE 0358-e1000-implementation-of-the-multi-queue-feature.txt ---
Subject: [PATCH] e1000: implementation of the multi-queue feature
From: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Date: 1128423803 -0400

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan at intel.com>
Signed-off-by: John Ronciak <john.ronciak at intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_main.c |  191 +++++++++++++++++++++++++++++++++++++++-
 1 files changed, 188 insertions(+), 3 deletions(-)

applies-to: 960e94cc7df451c287f9bc92fd4016c5b362c54f
24025e4ecf88743e1b3d46451b0e3f9de4bbcba5
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 5145b73..ce1044a 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -195,6 +195,11 @@ static int e1000_resume(struct pci_dev *
 static void e1000_netpoll (struct net_device *netdev);
 #endif
 
+#ifdef CONFIG_E1000_MQ
+/* for multiple Rx queues */
+void e1000_rx_schedule(void *data);
+#endif
+
 /* Exported from other modules */
 
 extern void e1000_check_options(struct e1000_adapter *adapter);
@@ -368,6 +373,9 @@ e1000_down(struct e1000_adapter *adapter
 	struct net_device *netdev = adapter->netdev;
 
 	e1000_irq_disable(adapter);
+#ifdef CONFIG_E1000_MQ
+	while (atomic_read(&adapter->rx_sched_call_data.count) != 0);
+#endif
 	free_irq(adapter->pdev->irq, netdev);
 #ifdef CONFIG_PCI_MSI
 	if(adapter->hw.mac_type > e1000_82547_rev_2 &&
@@ -810,9 +818,19 @@ e1000_remove(struct pci_dev *pdev)
 	if(!e1000_check_phy_reset_block(&adapter->hw))
 		e1000_phy_hw_reset(&adapter->hw);
 
+	kfree(adapter->tx_ring);
+	kfree(adapter->rx_ring);
+#ifdef CONFIG_E1000_NAPI
+	kfree(adapter->polling_netdev);
+#endif
+
 	iounmap(adapter->hw.hw_addr);
 	pci_release_regions(pdev);
 
+#ifdef CONFIG_E1000_MQ
+	free_percpu(adapter->cpu_netdev);
+	free_percpu(adapter->cpu_tx_ring);
+#endif
 	free_netdev(netdev);
 
 	pci_disable_device(pdev);
@@ -893,7 +911,21 @@ e1000_sw_init(struct e1000_adapter *adap
 		hw->master_slave = E1000_MASTER_SLAVE;
 	}
 
+#ifdef CONFIG_E1000_MQ
+	/* Number of supported queues */
+	switch (hw->mac_type) {
+	case e1000_82571:
+	case e1000_82572:
+		adapter->num_queues = 2;
+		break;
+	default:
+		adapter->num_queues = 1;
+		break;
+	}
+	adapter->num_queues = min(adapter->num_queues, num_online_cpus());
+#else
 	adapter->num_queues = 1;
+#endif
 
 	if (e1000_alloc_queues(adapter)) {
 		DPRINTK(PROBE, ERR, "Unable to allocate memory for queues\n");
@@ -909,6 +941,11 @@ e1000_sw_init(struct e1000_adapter *adap
 		set_bit(__LINK_STATE_START, &adapter->polling_netdev[i].state);
 	}
 #endif
+
+#ifdef CONFIG_E1000_MQ
+	e1000_setup_queue_mapping(adapter);
+#endif
+
 	atomic_set(&adapter->irq_sem, 1);
 	spin_lock_init(&adapter->stats_lock);
 
@@ -957,6 +994,39 @@ e1000_alloc_queues(struct e1000_adapter 
 	return E1000_SUCCESS;
 }
 
+#ifdef CONFIG_E1000_MQ
+static void __devinit
+e1000_setup_queue_mapping(struct e1000_adapter *adapter)
+{
+	int i, cpu;
+
+	adapter->rx_sched_call_data.func = e1000_rx_schedule;
+	adapter->rx_sched_call_data.info = adapter->netdev;
+	cpus_clear(adapter->rx_sched_call_data.cpumask);
+
+	adapter->cpu_netdev = alloc_percpu(struct net_device *);
+	adapter->cpu_tx_ring = alloc_percpu(struct e1000_tx_ring *);
+
+	lock_cpu_hotplug();
+	i = 0;
+	for_each_online_cpu(cpu) {
+		*per_cpu_ptr(adapter->cpu_tx_ring, cpu) = &adapter->tx_ring[i % adapter->num_queues];
+		/* This is incomplete because we'd like to assign separate
+		 * physical cpus to these netdev polling structures and
+		 * avoid saturating a subset of cpus.
+		 */
+		if (i < adapter->num_queues) {
+			*per_cpu_ptr(adapter->cpu_netdev, cpu) = &adapter->polling_netdev[i];
+			adapter->cpu_for_queue[i] = cpu;
+		} else
+			*per_cpu_ptr(adapter->cpu_netdev, cpu) = NULL;
+
+		i++;
+	}
+	unlock_cpu_hotplug();
+}
+#endif
+
 /**
  * e1000_open - Called when a network interface is made active
  * @netdev: network interface device structure
@@ -1178,8 +1248,21 @@ e1000_configure_tx(struct e1000_adapter 
 
 	/* Setup the HW Tx Head and Tail descriptor pointers */
 
-	E1000_WRITE_REG(&adapter->hw, TDH, 0);
-	E1000_WRITE_REG(&adapter->hw, TDT, 0);
+	switch (adapter->num_queues) {
+	case 2:
+		tdba = adapter->tx_ring[1].dma;
+		tdlen = adapter->tx_ring[1].count *
+			sizeof(struct e1000_tx_desc);
+		E1000_WRITE_REG(hw, TDBAL1, (tdba & 0x00000000ffffffffULL));
+		E1000_WRITE_REG(hw, TDBAH1, (tdba >> 32));
+		E1000_WRITE_REG(hw, TDLEN1, tdlen);
+		E1000_WRITE_REG(hw, TDH1, 0);
+		E1000_WRITE_REG(hw, TDT1, 0);
+		adapter->tx_ring[1].tdh = E1000_TDH1;
+		adapter->tx_ring[1].tdt = E1000_TDT1;
+		/* Fall Through */
+	case 1:
+	default:
 		tdba = adapter->tx_ring[0].dma;
 		tdlen = adapter->tx_ring[0].count *
 			sizeof(struct e1000_tx_desc);
@@ -1190,6 +1273,8 @@ e1000_configure_tx(struct e1000_adapter 
 		E1000_WRITE_REG(hw, TDT, 0);
 		adapter->tx_ring[0].tdh = E1000_TDH;
 		adapter->tx_ring[0].tdt = E1000_TDT;
+		break;
+	}
 
 	/* Set the default values for the Tx Inter Packet Gap timer */
 
@@ -1222,7 +1307,7 @@ e1000_configure_tx(struct e1000_adapter 
 	tctl = E1000_READ_REG(hw, TCTL);
 
 	tctl &= ~E1000_TCTL_CT;
-	tctl |= E1000_TCTL_EN | E1000_TCTL_PSP |
+	tctl |= E1000_TCTL_EN | E1000_TCTL_PSP | E1000_TCTL_RTLC |
 		(E1000_COLLISION_THRESHOLD << E1000_CT_SHIFT);
 
 	E1000_WRITE_REG(hw, TCTL, tctl);
@@ -1518,6 +1603,21 @@ e1000_configure_rx(struct e1000_adapter 
 
 	/* Setup the HW Rx Head and Tail Descriptor Pointers and
 	 * the Base and Length of the Rx Descriptor Ring */
+	switch (adapter->num_queues) {
+#ifdef CONFIG_E1000_MQ
+	case 2:
+		rdba = adapter->rx_ring[1].dma;
+		E1000_WRITE_REG(hw, RDBAL1, (rdba & 0x00000000ffffffffULL));
+		E1000_WRITE_REG(hw, RDBAH1, (rdba >> 32));
+		E1000_WRITE_REG(hw, RDLEN1, rdlen);
+		E1000_WRITE_REG(hw, RDH1, 0);
+		E1000_WRITE_REG(hw, RDT1, 0);
+		adapter->rx_ring[1].rdh = E1000_RDH1;
+		adapter->rx_ring[1].rdt = E1000_RDT1;
+		/* Fall Through */
+#endif
+	case 1:
+	default:
 		rdba = adapter->rx_ring[0].dma;
 		E1000_WRITE_REG(hw, RDBAL, (rdba & 0x00000000ffffffffULL));
 		E1000_WRITE_REG(hw, RDBAH, (rdba >> 32));
@@ -1527,6 +1627,47 @@ e1000_configure_rx(struct e1000_adapter 
 		adapter->rx_ring[0].rdh = E1000_RDH;
 		adapter->rx_ring[0].rdt = E1000_RDT;
 		break;
+	}
+
+#ifdef CONFIG_E1000_MQ
+	if (adapter->num_queues > 1) {
+		uint32_t random[10];
+
+		get_random_bytes(&random[0], 40);
+
+		if (hw->mac_type <= e1000_82572) {
+			E1000_WRITE_REG(hw, RSSIR, 0);
+			E1000_WRITE_REG(hw, RSSIM, 0);
+		}
+
+		switch (adapter->num_queues) {
+		case 2:
+		default:
+			reta = 0x00800080;
+			mrqc = E1000_MRQC_ENABLE_RSS_2Q;
+			break;
+		}
+
+		/* Fill out redirection table */
+		for (i = 0; i < 32; i++)
+			E1000_WRITE_REG_ARRAY(hw, RETA, i, reta);
+		/* Fill out hash function seeds */
+		for (i = 0; i < 10; i++)
+			E1000_WRITE_REG_ARRAY(hw, RSSRK, i, random[i]);
+
+		mrqc |= (E1000_MRQC_RSS_FIELD_IPV4 |
+			 E1000_MRQC_RSS_FIELD_IPV4_TCP);
+		E1000_WRITE_REG(hw, MRQC, mrqc);
+	}
+
+	/* Multiqueue and packet checksumming are mutually exclusive. */
+	if (hw->mac_type >= e1000_82571) {
+		rxcsum = E1000_READ_REG(hw, RXCSUM);
+		rxcsum |= E1000_RXCSUM_PCSD;
+		E1000_WRITE_REG(hw, RXCSUM, rxcsum);
+	}
+
+#else
 
 	/* Enable 82543 Receive Checksum Offload for TCP and UDP */
 	if (hw->mac_type >= e1000_82543) {
@@ -1546,6 +1687,7 @@ e1000_configure_rx(struct e1000_adapter 
 		}
 		E1000_WRITE_REG(hw, RXCSUM, rxcsum);
 	}
+#endif /* CONFIG_E1000_MQ */
 
 	if (hw->mac_type == e1000_82573)
 		E1000_WRITE_REG(hw, ERT, 0x0100);
@@ -2488,7 +2630,12 @@ e1000_xmit_frame(struct sk_buff *skb, st
 	unsigned int f;
 	len -= skb->data_len;
 
+#ifdef CONFIG_E1000_MQ
+	tx_ring = *per_cpu_ptr(adapter->cpu_tx_ring, smp_processor_id());
+#else
 	tx_ring = adapter->tx_ring;
+#endif
+
 	if (unlikely(skb->len <= 0)) {
 		dev_kfree_skb_any(skb);
 		return NETDEV_TX_OK;
@@ -2879,6 +3026,29 @@ e1000_update_stats(struct e1000_adapter 
 	spin_unlock_irqrestore(&adapter->stats_lock, flags);
 }
 
+#ifdef CONFIG_E1000_MQ
+void
+e1000_rx_schedule(void *data)
+{
+	struct net_device *poll_dev, *netdev = data;
+	struct e1000_adapter *adapter = netdev->priv;
+	int this_cpu = get_cpu();
+
+	poll_dev = *per_cpu_ptr(adapter->cpu_netdev, this_cpu);
+	if (poll_dev == NULL) {
+		put_cpu();
+		return;
+	}
+
+	if (likely(netif_rx_schedule_prep(poll_dev)))
+		__netif_rx_schedule(poll_dev);
+	else
+		e1000_irq_enable(adapter);
+
+	put_cpu();
+}
+#endif
+
 /**
  * e1000_intr - Interrupt Handler
  * @irq: interrupt number
@@ -2907,12 +3077,27 @@ e1000_intr(int irq, void *data, struct p
 	atomic_inc(&adapter->irq_sem);
 	E1000_WRITE_REG(hw, IMC, ~0);
 	E1000_WRITE_FLUSH(hw);
+#ifdef CONFIG_E1000_MQ
+	if (atomic_read(&adapter->rx_sched_call_data.count) == 0) {
+		cpu_set(adapter->cpu_for_queue[0],
+			adapter->rx_sched_call_data.cpumask);
+		for (i = 1; i < adapter->num_queues; i++) {
+			cpu_set(adapter->cpu_for_queue[i],
+				adapter->rx_sched_call_data.cpumask);
+			atomic_inc(&adapter->irq_sem);
+		}
+		atomic_set(&adapter->rx_sched_call_data.count, i);
+		smp_call_async_mask(&adapter->rx_sched_call_data);
+	} else {
+		printk("call_data.count == %u\n", atomic_read(&adapter->rx_sched_call_data.count));
 	}
 #else
 	if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0])))
 		__netif_rx_schedule(&adapter->polling_netdev[0]);
 	else
 		e1000_irq_enable(adapter);
+#endif
+#else
 	/* Writing IMC and IMS is needed for 82547.
 	   Due to Hub Link bus being occupied, an interrupt
 	   de-assertion message is not able to be sent.
---
0.99.8.GIT


--- NEW FILE 0359-e1000-Enable-custom-configuration-bits-for-82571-2-controllers.txt ---
Subject: [PATCH] e1000: Enable custom configuration bits for 82571/2 controllers
From: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Date: 1128423862 -0400

Enable custom configuration bits for 82571/2 controllers. The bits are
required for correct functionality of these controllers.

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan at intel.com>
Signed-off-by: John Ronciak <john.ronciak at intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_main.c |   23 +++++++++++++++++++++++
 1 files changed, 23 insertions(+), 0 deletions(-)

applies-to: 4ab263116b31128c40dcad3e22b26a46fae87ab4
2ae76d98fb9f0a9226dd62cf0a0b7547507d2862
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index ce1044a..ad92115 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1151,6 +1151,7 @@ e1000_setup_tx_resources(struct e1000_ad
 		return -ENOMEM;
 	}
 	memset(txdr->buffer_info, 0, size);
+	memset(&txdr->previous_buffer_info, 0, sizeof(struct e1000_buffer));
 
 	/* round up to nearest 4K */
 
@@ -1199,6 +1200,7 @@ setup_tx_desc_die:
 
 	txdr->next_to_use = 0;
 	txdr->next_to_clean = 0;
+	spin_lock_init(&txdr->tx_lock);
 
 	return 0;
 }
@@ -1312,6 +1314,19 @@ e1000_configure_tx(struct e1000_adapter 
 
 	E1000_WRITE_REG(hw, TCTL, tctl);
 
+	if (hw->mac_type == e1000_82571 || hw->mac_type == e1000_82572) {
+		tarc = E1000_READ_REG(hw, TARC0);
+		tarc |= ((1 << 25) | (1 << 21));
+		E1000_WRITE_REG(hw, TARC0, tarc);
+		tarc = E1000_READ_REG(hw, TARC1);
+		tarc |= (1 << 25);
+		if (tctl & E1000_TCTL_MULR)
+			tarc &= ~(1 << 28);
+		else
+			tarc |= (1 << 28);
+		E1000_WRITE_REG(hw, TARC1, tarc);
+	}
+
 	e1000_config_collision_dist(hw);
 
 	/* Setup Transmit Descriptor Settings for eop descriptor */
@@ -1601,6 +1616,14 @@ e1000_configure_rx(struct e1000_adapter 
 				1000000000 / (adapter->itr * 256));
 	}
 
+	if (hw->mac_type >= e1000_82571) {
+		/* Reset delay timers after every interrupt */
+		ctrl_ext = E1000_READ_REG(hw, CTRL_EXT);
+		ctrl_ext |= E1000_CTRL_EXT_CANC;
+		E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext);
+		E1000_WRITE_FLUSH(hw);
+	}
+
 	/* Setup the HW Rx Head and Tail Descriptor Pointers and
 	 * the Base and Length of the Rx Descriptor Ring */
 	switch (adapter->num_queues) {
---
0.99.8.GIT


--- NEW FILE 0360-e1000-Fixes-for-packet-split-related-issues.txt ---
Subject: [PATCH] e1000: Fixes for packet split related issues
From: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Date: 1128423944 -0400

Fixes for packet split related issues
  * On platforms where PAGE_SIZE > 4K, driver will use only required number of
    pages compared to always using 3 pages.
  * Packet split won't be used if the PAGE_SIZE is > 16K
  * Adds a statistics counter to splits.
  * Setting the non Null ptr to zero sized buffers to solve packet split
    receive descriptor error
  * When the no of pages needed is calculated, the header buffer is not
    included for a given MTU.

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan at intel.com>
Signed-off-by: John Ronciak <john.ronciak at intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000.h         |    7 ++-
 drivers/net/e1000/e1000_ethtool.c |    3 +
 drivers/net/e1000/e1000_main.c    |   88 +++++++++++++++++++++++--------------
 3 files changed, 60 insertions(+), 38 deletions(-)

applies-to: 2f44f6d13bedba9235b1cc12aaa0f2cce61af78f
e4c811c9d2f2728ce15440c99b3b44b72799b43f
diff --git a/drivers/net/e1000/e1000.h b/drivers/net/e1000/e1000.h
index 9b7274b..3f653a9 100644
--- a/drivers/net/e1000/e1000.h
+++ b/drivers/net/e1000/e1000.h
@@ -169,8 +169,8 @@ struct e1000_buffer {
 	uint16_t next_to_watch;
 };
 
-struct e1000_ps_page { struct page *ps_page[MAX_PS_BUFFERS]; };
-struct e1000_ps_page_dma { uint64_t ps_page_dma[MAX_PS_BUFFERS]; };
+struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; };
+struct e1000_ps_page_dma { uint64_t ps_page_dma[PS_PAGE_BUFFERS]; };
 
 struct e1000_tx_ring {
 	/* pointer to the descriptor ring memory */
@@ -300,10 +300,11 @@ struct e1000_adapter {
 
 	uint64_t hw_csum_err;
 	uint64_t hw_csum_good;
+	uint64_t rx_hdr_split;
 	uint32_t rx_int_delay;
 	uint32_t rx_abs_int_delay;
 	boolean_t rx_csum;
-	boolean_t rx_ps;
+	unsigned int rx_ps_pages;
 	uint32_t gorcl;
 	uint64_t gorcl_old;
 	uint16_t rx_ps_bsize0;
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 6e7e34f..183b583 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -91,7 +91,8 @@ static const struct e1000_stats e1000_gs
 	{ "tx_flow_control_xoff", E1000_STAT(stats.xofftxc) },
 	{ "rx_long_byte_count", E1000_STAT(stats.gorcl) },
 	{ "rx_csum_offload_good", E1000_STAT(hw_csum_good) },
-	{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }
+	{ "rx_csum_offload_errors", E1000_STAT(hw_csum_err) },
+	{ "rx_header_split", E1000_STAT(rx_hdr_split) },
 };
 #define E1000_STATS_LEN	\
 	sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats)
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index ad92115..090229f 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1484,12 +1484,16 @@ e1000_setup_all_rx_resources(struct e100
  * e1000_setup_rctl - configure the receive control registers
  * @adapter: Board private structure
  **/
-
+#define PAGE_USE_COUNT(S) (((S) >> PAGE_SHIFT) + \
+			(((S) & (PAGE_SIZE - 1)) ? 1 : 0))
 static void
 e1000_setup_rctl(struct e1000_adapter *adapter)
 {
 	uint32_t rctl, rfctl;
 	uint32_t psrctl = 0;
+#ifdef CONFIG_E1000_PACKET_SPLIT
+	uint32_t pages = 0;
+#endif
 
 	rctl = E1000_READ_REG(&adapter->hw, RCTL);
 
@@ -1543,11 +1547,14 @@ e1000_setup_rctl(struct e1000_adapter *a
 	 * followed by the page buffers.  Therefore, skb->data is
 	 * sized to hold the largest protocol header.
 	 */
-	adapter->rx_ps = (adapter->hw.mac_type > e1000_82547_rev_2) 
-			  && (adapter->netdev->mtu 
-	                      < ((3 * PAGE_SIZE) + adapter->rx_ps_bsize0));
+	pages = PAGE_USE_COUNT(adapter->netdev->mtu);
+	if ((adapter->hw.mac_type > e1000_82547_rev_2) && (pages <= 3) &&
+	    PAGE_SIZE <= 16384)
+		adapter->rx_ps_pages = pages;
+	else
+		adapter->rx_ps_pages = 0;
 #endif
-	if(adapter->rx_ps) {
+	if (adapter->rx_ps_pages) {
 		/* Configure extra packet-split registers */
 		rfctl = E1000_READ_REG(&adapter->hw, RFCTL);
 		rfctl |= E1000_RFCTL_EXTEN;
@@ -1559,12 +1566,19 @@ e1000_setup_rctl(struct e1000_adapter *a
 		
 		psrctl |= adapter->rx_ps_bsize0 >>
 			E1000_PSRCTL_BSIZE0_SHIFT;
-		psrctl |= PAGE_SIZE >>
-			E1000_PSRCTL_BSIZE1_SHIFT;
-		psrctl |= PAGE_SIZE <<
-			E1000_PSRCTL_BSIZE2_SHIFT;
-		psrctl |= PAGE_SIZE <<
-			E1000_PSRCTL_BSIZE3_SHIFT;
+
+		switch (adapter->rx_ps_pages) {
+		case 3:
+			psrctl |= PAGE_SIZE <<
+				E1000_PSRCTL_BSIZE3_SHIFT;
+		case 2:
+			psrctl |= PAGE_SIZE <<
+				E1000_PSRCTL_BSIZE2_SHIFT;
+		case 1:
+			psrctl |= PAGE_SIZE >>
+				E1000_PSRCTL_BSIZE1_SHIFT;
+			break;
+		}
 
 		E1000_WRITE_REG(&adapter->hw, PSRCTL, psrctl);
 	}
@@ -1590,7 +1604,7 @@ e1000_configure_rx(struct e1000_adapter 
 	int i;
 #endif
 
-	if(adapter->rx_ps) {
+	if (adapter->rx_ps_pages) {
 		rdlen = adapter->rx_ring[0].count *
 			sizeof(union e1000_rx_desc_packet_split);
 		adapter->clean_rx = e1000_clean_rx_irq_ps;
@@ -1700,8 +1714,8 @@ e1000_configure_rx(struct e1000_adapter 
 
 			/* Enable 82571 IPv4 payload checksum for UDP fragments
 			 * Must be used in conjunction with packet-split. */
-			if((adapter->hw.mac_type > e1000_82547_rev_2) && 
-			   (adapter->rx_ps)) {
+			if ((hw->mac_type >= e1000_82571) && 
+			   (adapter->rx_ps_pages)) {
 				rxcsum |= E1000_RXCSUM_IPPCSE;
 			}
 		} else {
@@ -1906,7 +1920,7 @@ e1000_clean_rx_ring(struct e1000_adapter
 			dev_kfree_skb(buffer_info->skb);
 			buffer_info->skb = NULL;
 
-			for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+			for(j = 0; j < adapter->rx_ps_pages; j++) {
 				if(!ps_page->ps_page[j]) break;
 				pci_unmap_single(pdev,
 						 ps_page_dma->ps_page_dma[j],
@@ -3551,7 +3565,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
 		/* Good Receive */
 		skb_put(skb, length);
 
-		for(j = 0; j < PS_PAGE_BUFFERS; j++) {
+		for(j = 0; j < adapter->rx_ps_pages; j++) {
 			if(!(length = le16_to_cpu(rx_desc->wb.upper.length[j])))
 				break;
 
@@ -3572,11 +3586,13 @@ e1000_clean_rx_irq_ps(struct e1000_adapt
 				  rx_desc->wb.lower.hi_dword.csum_ip.csum, skb);
 		skb->protocol = eth_type_trans(skb, netdev);
 
-#ifdef HAVE_RX_ZERO_COPY
 		if(likely(rx_desc->wb.upper.header_status &
-			  E1000_RXDPS_HDRSTAT_HDRSP))
+			  E1000_RXDPS_HDRSTAT_HDRSP)) {
+			adapter->rx_hdr_split++;
+#ifdef HAVE_RX_ZERO_COPY
 			skb_shinfo(skb)->zero_copy = TRUE;
 #endif
+	        }
 #ifdef CONFIG_E1000_NAPI
 		if(unlikely(adapter->vlgrp && (staterr & E1000_RXD_STAT_VP))) {
 			vlan_hwaccel_receive_skb(skb, adapter->vlgrp,
@@ -3740,22 +3756,26 @@ e1000_alloc_rx_buffers_ps(struct e1000_a
 		rx_desc = E1000_RX_DESC_PS(*rx_ring, i);
 
 		for(j = 0; j < PS_PAGE_BUFFERS; j++) {
-			if(unlikely(!ps_page->ps_page[j])) {
-				ps_page->ps_page[j] =
-					alloc_page(GFP_ATOMIC);
-				if(unlikely(!ps_page->ps_page[j]))
-					goto no_buffers;
-				ps_page_dma->ps_page_dma[j] =
-					pci_map_page(pdev,
-						     ps_page->ps_page[j],
-						     0, PAGE_SIZE,
-						     PCI_DMA_FROMDEVICE);
-			}
-			/* Refresh the desc even if buffer_addrs didn't
-			 * change because each write-back erases this info.
-			 */
-			rx_desc->read.buffer_addr[j+1] =
-				cpu_to_le64(ps_page_dma->ps_page_dma[j]);
+			if (j < adapter->rx_ps_pages) {
+				if (likely(!ps_page->ps_page[j])) {
+					ps_page->ps_page[j] =
+						alloc_page(GFP_ATOMIC);
+					if (unlikely(!ps_page->ps_page[j]))
+						goto no_buffers;
+					ps_page_dma->ps_page_dma[j] =
+						pci_map_page(pdev,
+							    ps_page->ps_page[j],
+							    0, PAGE_SIZE,
+							    PCI_DMA_FROMDEVICE);
+				}
+				/* Refresh the desc even if buffer_addrs didn't
+				 * change because each write-back erases 
+				 * this info.
+				 */
+				rx_desc->read.buffer_addr[j+1] =
+				     cpu_to_le64(ps_page_dma->ps_page_dma[j]);
+			} else
+				rx_desc->read.buffer_addr[j+1] = ~0;
 		}
 
 		skb = dev_alloc_skb(adapter->rx_ps_bsize0 + NET_IP_ALIGN);
---
0.99.8.GIT


--- NEW FILE 0361-e1000-Added-msleep_interruptible-delay.txt ---
Subject: [PATCH] e1000: Added msleep_interruptible delay
From: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Date: 1128424044 -0400

added msleep_interruptible delay right before returning from diag_test to allow
the phy to recover from reset

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan at intel.com>
Signed-off-by: John Ronciak <john.ronciak at intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_ethtool.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

applies-to: 0806fd1239c088d970db38c9a5bfec9b35ce3477
352c9f854cb197581d7135d1276742fd76b53c25
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 183b583..ee66947 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1544,6 +1544,7 @@ e1000_diag_test(struct net_device *netde
 		data[2] = 0;
 		data[3] = 0;
 	}
+	msleep_interruptible(4 * 1000);
 }
 
 static void
---
0.99.8.GIT


--- NEW FILE 0362-e1000-Flush-shadow-RAM.txt ---
Subject: [PATCH] e1000: Flush shadow RAM
From: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Date: 1128424099 -0400

Flush shadow RAM to save updates to ASF related bits for 82573 controllers.
These bits are past the first 63 words of NVM.

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan at intel.com>
Signed-off-by: John Ronciak <john.ronciak at intel.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_ethtool.c |    6 ++++--
 drivers/net/e1000/e1000_hw.c      |    1 +
 2 files changed, 5 insertions(+), 2 deletions(-)

applies-to: 938d630ff6ef3de60fcb6111bbe253a832ca019f
a7990ba60adc46a808c737443393fdfecdc82593
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index ee66947..6b9acc7 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -547,8 +547,10 @@ e1000_set_eeprom(struct net_device *netd
 	ret_val = e1000_write_eeprom(hw, first_word,
 				     last_word - first_word + 1, eeprom_buff);
 
-	/* Update the checksum over the first part of the EEPROM if needed */
-	if((ret_val == 0) && first_word <= EEPROM_CHECKSUM_REG)
+	/* Update the checksum over the first part of the EEPROM if needed 
+	 * and flush shadow RAM for 82573 conrollers */
+	if((ret_val == 0) && ((first_word <= EEPROM_CHECKSUM_REG) || 
+				(hw->mac_type == e1000_82573)))
 		e1000_update_eeprom_checksum(hw);
 
 	kfree(eeprom_buff);
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 7d627dd..8fc876d 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -717,6 +717,7 @@ e1000_init_hw(struct e1000_hw *hw)
     default:
         break;
     case e1000_82571:
+    case e1000_82572:
         ctrl = E1000_READ_REG(hw, TXDCTL1);
         ctrl &= ~E1000_TXDCTL_WTHRESH;
         ctrl |= E1000_TXDCTL_COUNT_DESC | E1000_TXDCTL_FULL_TX_DESC_WB;
---
0.99.8.GIT


--- NEW FILE 0363-e1000-fix-warnings.txt ---
Subject: [PATCH] e1000: fix warnings
From: Jeff Garzik <jgarzik at pobox.com>
Date: 1128424423 -0400

---

 drivers/net/e1000/e1000_main.c |   15 +++++++++------
 1 files changed, 9 insertions(+), 6 deletions(-)

applies-to: 5691856aa31edcf1ab15c12c777e9b1aff3a7d70
be2b28ed3bb3dd3952e10fb72623b23c5d8b4795
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 090229f..dd79449 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -777,12 +777,12 @@ e1000_remove(struct pci_dev *pdev)
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	uint32_t ctrl_ext;
 	uint32_t manc, swsm;
-
-	flush_scheduled_work();
 #ifdef CONFIG_E1000_NAPI
 	int i;
 #endif
 
+	flush_scheduled_work();
+
 	if(adapter->hw.mac_type >= e1000_82540 &&
 	   adapter->hw.media_type == e1000_media_type_copper) {
 		manc = E1000_READ_REG(&adapter->hw, MANC);
@@ -3100,7 +3100,9 @@ e1000_intr(int irq, void *data, struct p
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint32_t icr = E1000_READ_REG(hw, ICR);
+#ifdef CONFIG_E1000_MQ
 	int i;
+#endif
 
 	if(unlikely(!icr))
 		return IRQ_NONE;  /* Not our interrupt */
@@ -3128,13 +3130,14 @@ e1000_intr(int irq, void *data, struct p
 	} else {
 		printk("call_data.count == %u\n", atomic_read(&adapter->rx_sched_call_data.count));
 	}
-#else
+#else /* if !CONFIG_E1000_MQ */
 	if (likely(netif_rx_schedule_prep(&adapter->polling_netdev[0])))
 		__netif_rx_schedule(&adapter->polling_netdev[0]);
 	else
 		e1000_irq_enable(adapter);
-#endif
-#else
+#endif /* CONFIG_E1000_MQ */
+
+#else /* if !CONFIG_E1000_NAPI */
 	/* Writing IMC and IMS is needed for 82547.
 	   Due to Hub Link bus being occupied, an interrupt
 	   de-assertion message is not able to be sent.
@@ -3158,7 +3161,7 @@ e1000_intr(int irq, void *data, struct p
 	if(hw->mac_type == e1000_82547 || hw->mac_type == e1000_82547_rev_2)
 		e1000_irq_enable(adapter);
 
-#endif
+#endif /* CONFIG_E1000_NAPI */
 
 	return IRQ_HANDLED;
 }
---
0.99.8.GIT


--- NEW FILE 0364-AX.25-Delete-debug-printk-from-mkiss-driver.txt ---
Subject: [PATCH] AX.25: Delete debug printk from mkiss driver
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128424824 +0100

Signed-off-by: Ralf Baechle DL5RB <ralf at linux-mips.org>

--

 drivers/net/hamradio/mkiss.c |    1 -
 1 files changed, 1 deletion(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/hamradio/mkiss.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

applies-to: 53a3edbaac116616c4bf9977f69a7b7a84749ffe
96eb549c0c20cf63ca13fac71d9d406701f744a6
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index d9fe64b..793ae12 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -765,7 +765,6 @@ static int mkiss_ioctl(struct tty_struct
 
 	case SIOCSIFHWADDR: {
 		char addr[AX25_ADDR_LEN];
-printk(KERN_INFO "In SIOCSIFHWADDR");
 
 		if (copy_from_user(&addr,
 		                   (void __user *) arg, AX25_ADDR_LEN)) {
---
0.99.8.GIT


--- NEW FILE 0365-AX.25-Convert-mkiss.c-to-DEFINE_RWLOCK.txt ---
Subject: [PATCH] AX.25: Convert mkiss.c to DEFINE_RWLOCK
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128424936 +0100

Signed-off-by: Ingo Molnar <mingo at elte.hu>
Signed-off-by: Ralf Baechle DL5RB <ralf at linux-mips.org>

 drivers/net/hamradio/mkiss.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/hamradio/mkiss.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 32c23d9653d164e2f631970859d7b2e6ee25a003
d5919586265d36c6694a5d10ba589c02806873b6
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 793ae12..331a75c 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -622,7 +622,7 @@ static void ax_setup(struct net_device *
  * best way to fix this is to use a rwlock in the tty struct, but for now we
  * use a single global rwlock for all ttys in ppp line discipline.
  */
-static rwlock_t disc_data_lock = RW_LOCK_UNLOCKED;
+static DEFINE_RWLOCK(disc_data_lock);
 
 static struct mkiss *mkiss_get(struct tty_struct *tty)
 {
---
0.99.8.GIT


--- NEW FILE 0366-airo-fix-resume.txt ---
Subject: [PATCH] airo: fix resume
From: Michal Schmidt <xschmi00 at stud.feec.vutbr.cz>
Date: 1128426381 -0400

Cisco Aironet doesn't resume properly from swsusp, because the resume
method confuses a PM_EVENT_* for a PCI power state. It thinks that it is
resuming from PCI_D1 and doesn't do the necessary initialization of the
card.

Signed-off-by: Michal Schmidt <xschmi00 at stud.feec.vutbr.cz>

---

 drivers/net/wireless/airo.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

applies-to: b87f83c8215a65e1f1eb0b585d05afb21c15caaf
53232803241ae0f26b39897a4d4b37775837de00
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 746456c..cb429e7 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -5504,12 +5504,13 @@ static int airo_pci_resume(struct pci_de
 	struct net_device *dev = pci_get_drvdata(pdev);
 	struct airo_info *ai = dev->priv;
 	Resp rsp;
+	pci_power_t prev_state = pdev->current_state;
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_restore_state(pdev);
-	pci_enable_wake(pdev, pci_choose_state(pdev, ai->power), 0);
+	pci_enable_wake(pdev, PCI_D0, 0);
 
-	if (ai->power.event > 1) {
+	if (prev_state != PCI_D1) {
 		reset_card(dev, 0);
 		mpi_init_descriptors(ai);
 		setup_card(ai, dev->dev_addr, 0);
---
0.99.8.GIT


--- NEW FILE 0367-s2io-change-strncpy-length-arg-to-use-size-of-target.txt ---
Subject: [PATCH] s2io: change strncpy length arg to use size of target
From: John W. Linville <linville at tuxdriver.com>
Date: 1127944251 -0400

Use the size of the target array for the length argument to strncpy
instead of the size of the source or a magic number.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/s2io.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

applies-to: b4ab0478eb6b32d7c799d6161502c3d6f761e3d9
dbc2309d90b59fbb2676dc2e39150aa095e8c222
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 4b9f182..eff747c 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -4177,11 +4177,10 @@ static void s2io_ethtool_gdrvinfo(struct
 {
 	nic_t *sp = dev->priv;
 
-	strncpy(info->driver, s2io_driver_name, sizeof(s2io_driver_name));
-	strncpy(info->version, s2io_driver_version,
-		sizeof(s2io_driver_version));
-	strncpy(info->fw_version, "", 32);
-	strncpy(info->bus_info, pci_name(sp->pdev), 32);
+	strncpy(info->driver, s2io_driver_name, sizeof(info->driver));
+	strncpy(info->version, s2io_driver_version, sizeof(info->version));
+	strncpy(info->fw_version, "", sizeof(info->fw_version));
+	strncpy(info->bus_info, pci_name(sp->pdev), sizeof(info->bus_info));
 	info->regdump_len = XENA_REG_SPACE;
 	info->eedump_len = XENA_EEPROM_SPACE;
 	info->testinfo_len = S2IO_TEST_LEN;
---
0.99.8.GIT


--- NEW FILE 0368-netdrvr-s2io-Add-a-MODULE_VERSION-entry.txt ---
Subject: [PATCH] [netdrvr s2io] Add a MODULE_VERSION entry
From: John Linville <linville at tuxdriver.com>
Date: 1128426705 -0400

---

 drivers/net/s2io.c |   10 +++++++---
 1 files changed, 7 insertions(+), 3 deletions(-)

applies-to: 9d17c84d17c5a46e38fa07fef518f955c9944b5b
6c1792f4e8cf2ca03a8dd5ec4b162b9219e9268a
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index eff747c..fcf6110 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -65,9 +65,11 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
+#define DRV_VERSION "Version 2.0.9.1"
+
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
-static char s2io_driver_version[] = "Version 2.0.9.1";
+static char s2io_driver_version[] = DRV_VERSION;
 
 static inline int RXD_IS_UP2DT(RxD_t *rxdp)
 {
@@ -5635,6 +5637,8 @@ static void s2io_init_pci(nic_t * sp)
 
 MODULE_AUTHOR("Raghavendra Koushik <raghavendra.koushik at neterion.com>");
 MODULE_LICENSE("GPL");
+MODULE_VERSION(DRV_VERSION);
+
 module_param(tx_fifo_num, int, 0);
 module_param(rx_ring_num, int, 0);
 module_param_array(tx_fifo_len, uint, NULL, 0);
@@ -6013,7 +6017,7 @@ Defaulting to INTA\n");
 	if (sp->device_type & XFRAME_II_DEVICE) {
 		DBG_PRINT(ERR_DBG, "%s: Neterion Xframe II 10GbE adapter ",
 			  dev->name);
-		DBG_PRINT(ERR_DBG, "(rev %d), %s",
+		DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
 				get_xena_rev_id(sp->pdev),
 				s2io_driver_version);
 #ifdef CONFIG_2BUFF_MODE
@@ -6048,7 +6052,7 @@ Defaulting to INTA\n");
 	} else {
 		DBG_PRINT(ERR_DBG, "%s: Neterion Xframe I 10GbE adapter ",
 			  dev->name);
-		DBG_PRINT(ERR_DBG, "(rev %d), %s",
+		DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
 					get_xena_rev_id(sp->pdev),
 					s2io_driver_version);
 #ifdef CONFIG_2BUFF_MODE
---
0.99.8.GIT


--- NEW FILE 0369-bonding-replicate-IGMP-traffic-in-activebackup-mode.txt ---
Subject: [PATCH] bonding: replicate IGMP traffic in activebackup mode
From: John W. Linville <linville at tuxdriver.com>
Date: 1127944253 -0400

Replicate IGMP frames across all slaves in activebackup mode. This
ensures fail-over is rapid for multicast traffic as well. Otherwise,
multicast traffic will be lost until the next IGMP membership report
poll timeout.

This is conceptually similar to the treatment of IGMP traffic in
bond_alb_xmit. In that case, IGMP traffic transmitted on any slave
is re-routed to the active slave in order to ensure that multicast
traffic continues to be directed to the active receiver.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/bonding/bond_main.c |   53 ++++++++++++++++++++++++++++++++++++++-
 1 files changed, 51 insertions(+), 2 deletions(-)

applies-to: 2bcee321582d201510285d2cafff630a372761cd
075897ce3b1027fccb98f36dd1f18c07f5c374ef
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index fd62e43..2c9e63a 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -4240,6 +4240,39 @@ out:
 	return 0;
 }
 
+static void bond_activebackup_xmit_copy(struct sk_buff *skb,
+                                         struct bonding *bond,
+                                         struct slave *slave)
+{
+	struct sk_buff *skb2 = skb_copy(skb, GFP_ATOMIC);
+	struct ethhdr *eth_data;
+	u8 *hwaddr;
+	int res;
+
+	if (!skb2) {
+		printk(KERN_ERR DRV_NAME ": Error: "
+		       "bond_activebackup_xmit_copy(): skb_copy() failed\n");
+		return;
+	}
+
+	skb2->mac.raw = (unsigned char *)skb2->data;
+	eth_data = eth_hdr(skb2);
+
+	/* Pick an appropriate source MAC address */
+	hwaddr = slave->perm_hwaddr;
+	if (!memcmp(eth_data->h_source, hwaddr, ETH_ALEN))
+		hwaddr = bond->curr_active_slave->perm_hwaddr;
+
+	/* Set source MAC address appropriately */
+	memcpy(eth_data->h_source, hwaddr, ETH_ALEN);
+
+	res = bond_dev_queue_xmit(bond, skb2, slave->dev);
+	if (res)
+		dev_kfree_skb(skb2);
+
+	return;
+}
+
 /*
  * in active-backup mode, we know that bond->curr_active_slave is always valid if
  * the bond has a usable interface.
@@ -4256,10 +4289,26 @@ static int bond_xmit_activebackup(struct
 		goto out;
 	}
 
-	if (bond->curr_active_slave) { /* one usable interface */
-		res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
+	if (!bond->curr_active_slave)
+		goto out;
+
+	/* Xmit IGMP frames on all slaves to ensure rapid fail-over
+	   for multicast traffic on snooping switches */
+	if (skb->protocol == __constant_htons(ETH_P_IP) &&
+	    skb->nh.iph->protocol == IPPROTO_IGMP) {
+		struct slave *slave, *active_slave;
+		int i;
+
+		active_slave = bond->curr_active_slave;
+		bond_for_each_slave_from_to(bond, slave, i, active_slave->next,
+		                            active_slave->prev)
+			if (IS_UP(slave->dev) &&
+			    (slave->link == BOND_LINK_UP))
+				bond_activebackup_xmit_copy(skb, bond, slave);
 	}
 
+	res = bond_dev_queue_xmit(bond, skb, bond->curr_active_slave->dev);
+
 out:
 	if (res) {
 		/* no suitable interface, frame not sent */
---
0.99.8.GIT


--- NEW FILE 0371-wireless-ipw2200-remove-redundant-return-statement.txt ---
Subject: [PATCH] [wireless ipw2200] remove redundant return statement
From: Mateusz Berezecki <mateuszb at gmail.com>
Date: 1128428040 -0400

---

 drivers/net/wireless/ipw2200.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

applies-to: a795da3ac5c888f16b96082ddbd3d01c8c05493d
e2608361be343e6220e0a87e04ff224eb037df31
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 7ea9bd5..de4e6c2 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -5318,8 +5318,6 @@ static int ipw_wx_set_freq(struct net_de
 
 	IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
 	return ipw_set_channel(priv, (u8) fwrq->m);
-
-	return 0;
 }
 
 static int ipw_wx_get_freq(struct net_device *dev,
---
0.99.8.GIT


--- NEW FILE 0534-S2io-Offline-diagnostics-fixes.txt ---
Subject: [PATCH] S2io: Offline diagnostics fixes
From: ravinandan.arakali at neterion.com <ravinandan.arakali at neterion.com>
Date: 1129598780 -0700

This patch fixes the following bugs with offline diagnostics
code(run with "ethtool -t").

1. After running offline diagnostics, adapter would report
corrupted packets on receive. This was because of adapter not
being brought out of "RLDRAM test mode".
2. Current EEPROM test works only for Xframe I. Since Xframe II
uses different interface(SPI), support for this interface has
been added. Also, since SPI supports write access to all areas
of EEPROM, negative testing is done only for Xframe I.
3. Return values from subfunctions of offline diagnostics have
been corrected.
4. In register test, expected value from rx_queue_cfg register
is made to depend on adapter type.
5. After the test, need to restore values at EEPROM offsets
0x4F0 and 0x7F0. These locations were modified as part of test.
6. Use macro SPECIAL_REG_WRITE for write access to mc_rldram_test_ctrl
register. Also, couple of unnecessary writes to mc_rldram_test_ctrl
have been removed.

Signed-off-by: Ravinandan Arakali <ravinandan.arakali at neterion.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/s2io-regs.h |   11 ++
 drivers/net/s2io.c      |  241 ++++++++++++++++++++++++++++++-----------------
 2 files changed, 167 insertions(+), 85 deletions(-)

applies-to: b337d73229a69e399d4e4f7128b33ce734660e35
ad4ebed00fbf570411edbf6eb6c391e16b71df25
diff --git a/drivers/net/s2io-regs.h b/drivers/net/s2io-regs.h
index 7cefe55..00179bc 100644
--- a/drivers/net/s2io-regs.h
+++ b/drivers/net/s2io-regs.h
@@ -814,6 +814,17 @@ typedef struct _XENA_dev_config {
 	u64 rxgxs_ber_0;	/* CHANGED */
 	u64 rxgxs_ber_1;	/* CHANGED */
 
+	u64 spi_control;
+#define SPI_CONTROL_KEY(key)		vBIT(key,0,4)
+#define SPI_CONTROL_BYTECNT(cnt)	vBIT(cnt,29,3)
+#define SPI_CONTROL_CMD(cmd)		vBIT(cmd,32,8)
+#define SPI_CONTROL_ADDR(addr)		vBIT(addr,40,24)
+#define SPI_CONTROL_SEL1		BIT(4)
+#define SPI_CONTROL_REQ			BIT(7)
+#define SPI_CONTROL_NACK		BIT(5)
+#define SPI_CONTROL_DONE		BIT(6)
+	u64 spi_data;
+#define SPI_DATA_WRITE(data,len)	vBIT(data,0,len)
 } XENA_dev_config_t;
 
 #define XENA_REG_SPACE	sizeof(XENA_dev_config_t)
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index fcf6110..30fbaf0 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -4378,29 +4378,53 @@ static int s2io_ethtool_setpause_data(st
  */
 
 #define S2IO_DEV_ID		5
-static int read_eeprom(nic_t * sp, int off, u32 * data)
+static int read_eeprom(nic_t * sp, int off, u64 * data)
 {
 	int ret = -1;
 	u32 exit_cnt = 0;
 	u64 val64;
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
-	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
-	    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
-	    I2C_CONTROL_CNTL_START;
-	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
-
-	while (exit_cnt < 5) {
-		val64 = readq(&bar0->i2c_control);
-		if (I2C_CONTROL_CNTL_END(val64)) {
-			*data = I2C_CONTROL_GET_DATA(val64);
-			ret = 0;
-			break;
+	if (sp->device_type == XFRAME_I_DEVICE) {
+		val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
+		    I2C_CONTROL_BYTE_CNT(0x3) | I2C_CONTROL_READ |
+		    I2C_CONTROL_CNTL_START;
+		SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+
+		while (exit_cnt < 5) {
+			val64 = readq(&bar0->i2c_control);
+			if (I2C_CONTROL_CNTL_END(val64)) {
+				*data = I2C_CONTROL_GET_DATA(val64);
+				ret = 0;
+				break;
+			}
+			msleep(50);
+			exit_cnt++;
 		}
-		msleep(50);
-		exit_cnt++;
 	}
 
+	if (sp->device_type == XFRAME_II_DEVICE) {
+		val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
+			SPI_CONTROL_BYTECNT(0x3) | 
+			SPI_CONTROL_CMD(0x3) | SPI_CONTROL_ADDR(off);
+		SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+		val64 |= SPI_CONTROL_REQ;
+		SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+		while (exit_cnt < 5) {
+			val64 = readq(&bar0->spi_control);
+			if (val64 & SPI_CONTROL_NACK) {
+				ret = 1;
+				break;
+			} else if (val64 & SPI_CONTROL_DONE) {
+				*data = readq(&bar0->spi_data);
+				*data &= 0xffffff;
+				ret = 0;
+				break;
+			}
+			msleep(50);
+			exit_cnt++;
+		}
+	}
 	return ret;
 }
 
@@ -4419,28 +4443,53 @@ static int read_eeprom(nic_t * sp, int o
  *  0 on success, -1 on failure.
  */
 
-static int write_eeprom(nic_t * sp, int off, u32 data, int cnt)
+static int write_eeprom(nic_t * sp, int off, u64 data, int cnt)
 {
 	int exit_cnt = 0, ret = -1;
 	u64 val64;
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 
-	val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
-	    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA(data) |
-	    I2C_CONTROL_CNTL_START;
-	SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
-
-	while (exit_cnt < 5) {
-		val64 = readq(&bar0->i2c_control);
-		if (I2C_CONTROL_CNTL_END(val64)) {
-			if (!(val64 & I2C_CONTROL_NACK))
-				ret = 0;
-			break;
+	if (sp->device_type == XFRAME_I_DEVICE) {
+		val64 = I2C_CONTROL_DEV_ID(S2IO_DEV_ID) | I2C_CONTROL_ADDR(off) |
+		    I2C_CONTROL_BYTE_CNT(cnt) | I2C_CONTROL_SET_DATA((u32)data) |
+		    I2C_CONTROL_CNTL_START;
+		SPECIAL_REG_WRITE(val64, &bar0->i2c_control, LF);
+
+		while (exit_cnt < 5) {
+			val64 = readq(&bar0->i2c_control);
+			if (I2C_CONTROL_CNTL_END(val64)) {
+				if (!(val64 & I2C_CONTROL_NACK))
+					ret = 0;
+				break;
+			}
+			msleep(50);
+			exit_cnt++;
 		}
-		msleep(50);
-		exit_cnt++;
 	}
 
+	if (sp->device_type == XFRAME_II_DEVICE) {
+		int write_cnt = (cnt == 8) ? 0 : cnt;
+		writeq(SPI_DATA_WRITE(data,(cnt<<3)), &bar0->spi_data);
+
+		val64 = SPI_CONTROL_KEY(0x9) | SPI_CONTROL_SEL1 |
+			SPI_CONTROL_BYTECNT(write_cnt) | 
+			SPI_CONTROL_CMD(0x2) | SPI_CONTROL_ADDR(off);
+		SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+		val64 |= SPI_CONTROL_REQ;
+		SPECIAL_REG_WRITE(val64, &bar0->spi_control, LF);
+		while (exit_cnt < 5) {
+			val64 = readq(&bar0->spi_control);
+			if (val64 & SPI_CONTROL_NACK) {
+				ret = 1;
+				break;
+			} else if (val64 & SPI_CONTROL_DONE) {
+				ret = 0;
+				break;
+			}
+			msleep(50);
+			exit_cnt++;
+		}
+	}
 	return ret;
 }
 
@@ -4460,7 +4509,8 @@ static int write_eeprom(nic_t * sp, int 
 static int s2io_ethtool_geeprom(struct net_device *dev,
 			 struct ethtool_eeprom *eeprom, u8 * data_buf)
 {
-	u32 data, i, valid;
+	u32 i, valid;
+	u64 data;
 	nic_t *sp = dev->priv;
 
 	eeprom->magic = sp->pdev->vendor | (sp->pdev->device << 16);
@@ -4498,7 +4548,7 @@ static int s2io_ethtool_seeprom(struct n
 				u8 * data_buf)
 {
 	int len = eeprom->len, cnt = 0;
-	u32 valid = 0, data;
+	u64 valid = 0, data;
 	nic_t *sp = dev->priv;
 
 	if (eeprom->magic != (sp->pdev->vendor | (sp->pdev->device << 16))) {
@@ -4546,7 +4596,7 @@ static int s2io_ethtool_seeprom(struct n
 static int s2io_register_test(nic_t * sp, uint64_t * data)
 {
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
-	u64 val64 = 0;
+	u64 val64 = 0, exp_val;
 	int fail = 0;
 
 	val64 = readq(&bar0->pif_rd_swapper_fb);
@@ -4562,7 +4612,11 @@ static int s2io_register_test(nic_t * sp
 	}
 
 	val64 = readq(&bar0->rx_queue_cfg);
-	if (val64 != 0x0808080808080808ULL) {
+	if (sp->device_type == XFRAME_II_DEVICE)
+		exp_val = 0x0404040404040404ULL;
+	else
+		exp_val = 0x0808080808080808ULL;
+	if (val64 != exp_val) {
 		fail = 1;
 		DBG_PRINT(INFO_DBG, "Read Test level 3 fails\n");
 	}
@@ -4590,7 +4644,7 @@ static int s2io_register_test(nic_t * sp
 	}
 
 	*data = fail;
-	return 0;
+	return fail;
 }
 
 /**
@@ -4609,58 +4663,83 @@ static int s2io_register_test(nic_t * sp
 static int s2io_eeprom_test(nic_t * sp, uint64_t * data)
 {
 	int fail = 0;
-	u32 ret_data;
+	u64 ret_data, org_4F0, org_7F0;
+	u8 saved_4F0 = 0, saved_7F0 = 0;
+	struct net_device *dev = sp->dev;
 
 	/* Test Write Error at offset 0 */
-	if (!write_eeprom(sp, 0, 0, 3))
-		fail = 1;
+	/* Note that SPI interface allows write access to all areas
+	 * of EEPROM. Hence doing all negative testing only for Xframe I.
+	 */
+	if (sp->device_type == XFRAME_I_DEVICE)
+		if (!write_eeprom(sp, 0, 0, 3))
+			fail = 1;
+
+	/* Save current values at offsets 0x4F0 and 0x7F0 */
+	if (!read_eeprom(sp, 0x4F0, &org_4F0))
+		saved_4F0 = 1;
+	if (!read_eeprom(sp, 0x7F0, &org_7F0))
+		saved_7F0 = 1;
 
 	/* Test Write at offset 4f0 */
-	if (write_eeprom(sp, 0x4F0, 0x01234567, 3))
+	if (write_eeprom(sp, 0x4F0, 0x012345, 3))
 		fail = 1;
 	if (read_eeprom(sp, 0x4F0, &ret_data))
 		fail = 1;
 
-	if (ret_data != 0x01234567)
+	if (ret_data != 0x012345) {
+		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x4F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
 		fail = 1;
+	}
 
 	/* Reset the EEPROM data go FFFF */
-	write_eeprom(sp, 0x4F0, 0xFFFFFFFF, 3);
+	write_eeprom(sp, 0x4F0, 0xFFFFFF, 3);
 
 	/* Test Write Request Error at offset 0x7c */
-	if (!write_eeprom(sp, 0x07C, 0, 3))
-		fail = 1;
+	if (sp->device_type == XFRAME_I_DEVICE)
+		if (!write_eeprom(sp, 0x07C, 0, 3))
+			fail = 1;
 
-	/* Test Write Request at offset 0x7fc */
-	if (write_eeprom(sp, 0x7FC, 0x01234567, 3))
+	/* Test Write Request at offset 0x7f0 */
+	if (write_eeprom(sp, 0x7F0, 0x012345, 3))
 		fail = 1;
-	if (read_eeprom(sp, 0x7FC, &ret_data))
+	if (read_eeprom(sp, 0x7F0, &ret_data))
 		fail = 1;
 
-	if (ret_data != 0x01234567)
+	if (ret_data != 0x012345) {
+		DBG_PRINT(ERR_DBG, "%s: eeprom test error at offset 0x7F0. Data written %llx Data read %llx\n", dev->name, (u64)0x12345, ret_data); 
 		fail = 1;
+	}
 
 	/* Reset the EEPROM data go FFFF */
-	write_eeprom(sp, 0x7FC, 0xFFFFFFFF, 3);
-
-	/* Test Write Error at offset 0x80 */
-	if (!write_eeprom(sp, 0x080, 0, 3))
-		fail = 1;
-
-	/* Test Write Error at offset 0xfc */
-	if (!write_eeprom(sp, 0x0FC, 0, 3))
-		fail = 1;
+	write_eeprom(sp, 0x7F0, 0xFFFFFF, 3);
 
-	/* Test Write Error at offset 0x100 */
-	if (!write_eeprom(sp, 0x100, 0, 3))
-		fail = 1;
-
-	/* Test Write Error at offset 4ec */
-	if (!write_eeprom(sp, 0x4EC, 0, 3))
-		fail = 1;
+	if (sp->device_type == XFRAME_I_DEVICE) {
+		/* Test Write Error at offset 0x80 */
+		if (!write_eeprom(sp, 0x080, 0, 3))
+			fail = 1;
+
+		/* Test Write Error at offset 0xfc */
+		if (!write_eeprom(sp, 0x0FC, 0, 3))
+			fail = 1;
+
+		/* Test Write Error at offset 0x100 */
+		if (!write_eeprom(sp, 0x100, 0, 3))
+			fail = 1;
+
+		/* Test Write Error at offset 4ec */
+		if (!write_eeprom(sp, 0x4EC, 0, 3))
+			fail = 1;
+	}
+
+	/* Restore values at offsets 0x4F0 and 0x7F0 */
+	if (saved_4F0)
+		write_eeprom(sp, 0x4F0, org_4F0, 3);
+	if (saved_7F0)
+		write_eeprom(sp, 0x7F0, org_7F0, 3);
 
 	*data = fail;
-	return 0;
+	return fail;
 }
 
 /**
@@ -4742,7 +4821,7 @@ static int s2io_rldram_test(nic_t * sp, 
 {
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
-	int cnt, iteration = 0, test_pass = 0;
+	int cnt, iteration = 0, test_fail = 0;
 
 	val64 = readq(&bar0->adapter_control);
 	val64 &= ~ADAPTER_ECC_EN;
@@ -4750,7 +4829,7 @@ static int s2io_rldram_test(nic_t * sp, 
 
 	val64 = readq(&bar0->mc_rldram_test_ctrl);
 	val64 |= MC_RLDRAM_TEST_MODE;
-	writeq(val64, &bar0->mc_rldram_test_ctrl);
+	SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
 
 	val64 = readq(&bar0->mc_rldram_mrs);
 	val64 |= MC_RLDRAM_QUEUE_SIZE_ENABLE;
@@ -4778,17 +4857,12 @@ static int s2io_rldram_test(nic_t * sp, 
 		}
 		writeq(val64, &bar0->mc_rldram_test_d2);
 
-		val64 = (u64) (0x0000003fffff0000ULL);
+		val64 = (u64) (0x0000003ffffe0100ULL);
 		writeq(val64, &bar0->mc_rldram_test_add);
 
-
-		val64 = MC_RLDRAM_TEST_MODE;
-		writeq(val64, &bar0->mc_rldram_test_ctrl);
-
-		val64 |=
-		    MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE |
-		    MC_RLDRAM_TEST_GO;
-		writeq(val64, &bar0->mc_rldram_test_ctrl);
+		val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_WRITE |
+		    	MC_RLDRAM_TEST_GO;
+		SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
 
 		for (cnt = 0; cnt < 5; cnt++) {
 			val64 = readq(&bar0->mc_rldram_test_ctrl);
@@ -4800,11 +4874,8 @@ static int s2io_rldram_test(nic_t * sp, 
 		if (cnt == 5)
 			break;
 
-		val64 = MC_RLDRAM_TEST_MODE;
-		writeq(val64, &bar0->mc_rldram_test_ctrl);
-
-		val64 |= MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO;
-		writeq(val64, &bar0->mc_rldram_test_ctrl);
+		val64 = MC_RLDRAM_TEST_MODE | MC_RLDRAM_TEST_GO;
+		SPECIAL_REG_WRITE(val64, &bar0->mc_rldram_test_ctrl, LF);
 
 		for (cnt = 0; cnt < 5; cnt++) {
 			val64 = readq(&bar0->mc_rldram_test_ctrl);
@@ -4817,18 +4888,18 @@ static int s2io_rldram_test(nic_t * sp, 
 			break;
 
 		val64 = readq(&bar0->mc_rldram_test_ctrl);
-		if (val64 & MC_RLDRAM_TEST_PASS)
-			test_pass = 1;
+		if (!(val64 & MC_RLDRAM_TEST_PASS))
+			test_fail = 1;
 
 		iteration++;
 	}
 
-	if (!test_pass)
-		*data = 1;
-	else
-		*data = 0;
+	*data = test_fail;
 
-	return 0;
+	/* Bring the adapter out of test mode */
+	SPECIAL_REG_WRITE(0, &bar0->mc_rldram_test_ctrl, LF);
+
+	return test_fail;
 }
 
 /**
---
0.99.8.GIT


--- NEW FILE 0535-rcu-in-bpqether-driver.txt ---
Subject: [PATCH] rcu in bpqether driver.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1129549352 +0100

>From Suzanne Wood <suzannew at cs.pdx.edu>:

Clarify RCU implementation in bpqether.c.

Because bpq_new_device() calls list_add_rcu() and bpq_free_device() calls
list_del_rcu(), substitute list_for_each_entry_rcu() for
list_for_each_entry() in bpq_get_ax25_dev() and in bpq_seq_start().

Add rcu dereference protection in bpq_seq_next().

The rcu_read_lock()/unlock() in bpq_device_event() are removed because
netdev event handlers are called with RTNL locking in place.

FYI: bpq_free_device() calls list_del_rcu() which, per list.h, requires
synchronize_rcu() which can block or call_rcu() or call_rcu_bh() which
cannot block.  Herbert Xu notes that synchronization is done here by
unregister_netdevice().  This calls synchronize_net() which in turn uses
synchronize_rcu().

Signed-off-by: Ralf Baechle DL5RB <ralf at linux-mips.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/hamradio/bpqether.c |    9 +++------
 1 files changed, 3 insertions(+), 6 deletions(-)

applies-to: 37f236700d5e831fee6bf8494cd57753231ddf14
bc0a7438605c5e0cafdb32a3caf46254e146b116
diff --git a/drivers/net/hamradio/bpqether.c b/drivers/net/hamradio/bpqether.c
index 1756f0e..cb43a9d 100644
--- a/drivers/net/hamradio/bpqether.c
+++ b/drivers/net/hamradio/bpqether.c
@@ -144,7 +144,7 @@ static inline struct net_device *bpq_get
 {
 	struct bpqdev *bpq;
 
-	list_for_each_entry(bpq, &bpq_devices, bpq_list) {
+	list_for_each_entry_rcu(bpq, &bpq_devices, bpq_list) {
 		if (bpq->ethdev == dev)
 			return bpq->axdev;
 	}
@@ -399,7 +399,7 @@ static void *bpq_seq_start(struct seq_fi
 	if (*pos == 0)
 		return SEQ_START_TOKEN;
 	
-	list_for_each_entry(bpqdev, &bpq_devices, bpq_list) {
+	list_for_each_entry_rcu(bpqdev, &bpq_devices, bpq_list) {
 		if (i == *pos)
 			return bpqdev;
 	}
@@ -418,7 +418,7 @@ static void *bpq_seq_next(struct seq_fil
 		p = ((struct bpqdev *)v)->bpq_list.next;
 
 	return (p == &bpq_devices) ? NULL 
-		: list_entry(p, struct bpqdev, bpq_list);
+		: rcu_dereference(list_entry(p, struct bpqdev, bpq_list));
 }
 
 static void bpq_seq_stop(struct seq_file *seq, void *v)
@@ -561,8 +561,6 @@ static int bpq_device_event(struct notif
 	if (!dev_is_ethdev(dev))
 		return NOTIFY_DONE;
 
-	rcu_read_lock();
-
 	switch (event) {
 	case NETDEV_UP:		/* new ethernet device -> new BPQ interface */
 		if (bpq_get_ax25_dev(dev) == NULL)
@@ -581,7 +579,6 @@ static int bpq_device_event(struct notif
 	default:
 		break;
 	}
-	rcu_read_unlock();
 
 	return NOTIFY_DONE;
 }
---
0.99.8.GIT


--- NEW FILE 0536-SMACK-support-for-mkiss.txt ---
Subject: [PATCH] SMACK support for mkiss
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1129296489 +0100

SMACK (Stuttgart Modified Amateurradio CRC KISS) is a KISS variant that
uses CRC16 checksums to secure data transfers between the modem and host.
It's also used to communicate over a pty to applications such as Wampes.

Patches for Linux 2.4 by Thomas Osterried DL9SAU, upgraded to the latest
mkiss 2.6 mkiss driver by me.

Signed-off-by: Thomas Osterried DL9SAU <thomas at x-berg.in-berlin.de>
Signed-off-by: Ralf Baechle DL5RB <ralf at linux-mips.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/hamradio/Kconfig |    1 
 drivers/net/hamradio/mkiss.c |  178 +++++++++++++++++++++++++++++++++++-------
 2 files changed, 148 insertions(+), 31 deletions(-)

applies-to: 7331f97459c13f1f4bb18d8d2db6abd724ad6f7f
5793f4be23f0171b4999ca68a39a9157b44139f3
diff --git a/drivers/net/hamradio/Kconfig b/drivers/net/hamradio/Kconfig
index de087cd..896aa02 100644
--- a/drivers/net/hamradio/Kconfig
+++ b/drivers/net/hamradio/Kconfig
@@ -1,6 +1,7 @@
 config MKISS
 	tristate "Serial port KISS driver"
 	depends on AX25
+	select CRC16
 	---help---
 	  KISS is a protocol used for the exchange of data between a computer
 	  and a Terminal Node Controller (a small embedded system commonly
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 331a75c..7961f5b 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -14,13 +14,14 @@
  *
  * Copyright (C) Hans Alblas PE1AYX <hans at esrac.ele.tue.nl>
  * Copyright (C) 2004, 05 Ralf Baechle DL5RB <ralf at linux-mips.org>
+ * Copyright (C) 2004, 05 Thomas Osterried DL9SAU <thomas at x-berg.in-berlin.de>
  */
-
 #include <linux/config.h>
 #include <linux/module.h>
 #include <asm/system.h>
 #include <linux/bitops.h>
 #include <asm/uaccess.h>
+#include <linux/crc16.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/interrupt.h>
@@ -39,11 +40,6 @@
 
 #include <net/ax25.h>
 
-#ifdef CONFIG_INET
-#include <linux/ip.h>
-#include <linux/tcp.h>
-#endif
-
 #define AX_MTU		236
 
 /* SLIP/KISS protocol characters. */
@@ -80,9 +76,13 @@ struct mkiss {
 
 	int		mode;
         int		crcmode;	/* MW: for FlexNet, SMACK etc.  */
-#define CRC_MODE_NONE   0
-#define CRC_MODE_FLEX   1
-#define CRC_MODE_SMACK  2
+	int		crcauto;	/* CRC auto mode */
+
+#define CRC_MODE_NONE		0
+#define CRC_MODE_FLEX		1
+#define CRC_MODE_SMACK		2
+#define CRC_MODE_FLEX_TEST	3
+#define CRC_MODE_SMACK_TEST	4
 
 	atomic_t		refcnt;
 	struct semaphore	dead_sem;
@@ -151,6 +151,21 @@ static int check_crc_flex(unsigned char 
 	return 0;
 }
 
+static int check_crc_16(unsigned char *cp, int size)
+{
+	unsigned short crc = 0x0000;
+
+	if (size < 3)
+		return -1;
+
+	crc = crc16(0, cp, size);
+
+	if (crc != 0x0000)
+		return -1;
+
+	return 0;
+}
+
 /*
  * Standard encapsulation
  */
@@ -237,19 +252,42 @@ static void ax_bump(struct mkiss *ax)
 
 	spin_lock_bh(&ax->buflock);
 	if (ax->rbuff[0] > 0x0f) {
-		if (ax->rbuff[0] & 0x20) {
-		        ax->crcmode = CRC_MODE_FLEX;
+		if (ax->rbuff[0] & 0x80) {
+			if (check_crc_16(ax->rbuff, ax->rcount) < 0) {
+				ax->stats.rx_errors++;
+				spin_unlock_bh(&ax->buflock);
+
+				return;
+			}
+			if (ax->crcmode != CRC_MODE_SMACK && ax->crcauto) {
+				printk(KERN_INFO
+				       "mkiss: %s: Switchting to crc-smack\n",
+				       ax->dev->name);
+				ax->crcmode = CRC_MODE_SMACK;
+			}
+			ax->rcount -= 2;
+			*ax->rbuff &= ~0x80;
+		} else if (ax->rbuff[0] & 0x20)  {
 			if (check_crc_flex(ax->rbuff, ax->rcount) < 0) {
-			        ax->stats.rx_errors++;
+				ax->stats.rx_errors++;
+				spin_unlock_bh(&ax->buflock);
 				return;
 			}
+			if (ax->crcmode != CRC_MODE_FLEX && ax->crcauto) {
+				printk(KERN_INFO
+				       "mkiss: %s: Switchting to crc-flexnet\n",
+				       ax->dev->name);
+				ax->crcmode = CRC_MODE_FLEX;
+			}
 			ax->rcount -= 2;
-                        /* dl9sau bugfix: the trailling two bytes flexnet crc
-                         * will not be passed to the kernel. thus we have
-                         * to correct the kissparm signature, because it
-                         * indicates a crc but there's none
+
+			/*
+			 * dl9sau bugfix: the trailling two bytes flexnet crc
+			 * will not be passed to the kernel. thus we have to
+			 * correct the kissparm signature, because it indicates
+			 * a crc but there's none
 			 */
-                        *ax->rbuff &= ~0x20;
+			*ax->rbuff &= ~0x20;
 		}
  	}
 	spin_unlock_bh(&ax->buflock);
@@ -417,20 +455,69 @@ static void ax_encaps(struct net_device 
 	p = icp;
 
 	spin_lock_bh(&ax->buflock);
-        switch (ax->crcmode) {
-	         unsigned short crc;
+	if ((*p & 0x0f) != 0) {
+		/* Configuration Command (kissparms(1).
+		 * Protocol spec says: never append CRC.
+		 * This fixes a very old bug in the linux
+		 * kiss driver. -- dl9sau */
+		switch (*p & 0xff) {
+		case 0x85:
+			/* command from userspace especially for us,
+			 * not for delivery to the tnc */
+			if (len > 1) {
+				int cmd = (p[1] & 0xff);
+				switch(cmd) {
+				case 3:
+				  ax->crcmode = CRC_MODE_SMACK;
+				  break;
+				case 2:
+				  ax->crcmode = CRC_MODE_FLEX;
+				  break;
+				case 1:
+				  ax->crcmode = CRC_MODE_NONE;
+				  break;
+				case 0:
+				default:
+				  ax->crcmode = CRC_MODE_SMACK_TEST;
+				  cmd = 0;
+				}
+				ax->crcauto = (cmd ? 0 : 1);
+				printk(KERN_INFO "mkiss: %s: crc mode %s %d\n", ax->dev->name, (len) ? "set to" : "is", cmd);
+			}
+			spin_unlock_bh(&ax->buflock);
+			netif_start_queue(dev);
 
-	case CRC_MODE_FLEX:
-	         *p |= 0x20;
-	         crc = calc_crc_flex(p, len);
-		 count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
-		 break;
+			return;
+		default:
+			count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
+		}
+	} else {
+		unsigned short crc;
+		switch (ax->crcmode) {
+		case CRC_MODE_SMACK_TEST:
+			ax->crcmode  = CRC_MODE_FLEX_TEST;
+			printk(KERN_INFO "mkiss: %s: Trying crc-smack\n", ax->dev->name);
+			// fall through
+		case CRC_MODE_SMACK:
+			*p |= 0x80;
+			crc = swab16(crc16(0, p, len));
+			count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
+			break;
+		case CRC_MODE_FLEX_TEST:
+			ax->crcmode = CRC_MODE_NONE;
+			printk(KERN_INFO "mkiss: %s: Trying crc-flexnet\n", ax->dev->name);
+			// fall through
+		case CRC_MODE_FLEX:
+			*p |= 0x20;
+			crc = calc_crc_flex(p, len);
+			count = kiss_esc_crc(p, (unsigned char *)ax->xbuff, crc, len+2);
+			break;
+
+		default:
+			count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
+		}
+  	}
 
-	default:
-	         count = kiss_esc(p, (unsigned char *)ax->xbuff, len);
-		 break;
-	}
-	
 	set_bit(TTY_DO_WRITE_WAKEUP, &ax->tty->flags);
 	actual = ax->tty->driver->write(ax->tty, ax->xbuff, count);
 	ax->stats.tx_packets++;
@@ -439,8 +526,6 @@ static void ax_encaps(struct net_device 
 	ax->dev->trans_start = jiffies;
 	ax->xleft = count - actual;
 	ax->xhead = ax->xbuff + actual;
-
-	spin_unlock_bh(&ax->buflock);
 }
 
 /* Encapsulate an AX.25 packet and kick it into a TTY queue. */
@@ -643,6 +728,8 @@ static void mkiss_put(struct mkiss *ax)
 		up(&ax->dead_sem);
 }
 
+static int crc_force = 0;	/* Can be overridden with insmod */
+
 static int mkiss_open(struct tty_struct *tty)
 {
 	struct net_device *dev;
@@ -682,6 +769,33 @@ static int mkiss_open(struct tty_struct 
 	if (register_netdev(dev))
 		goto out_free_buffers;
 
+	/* after register_netdev() - because else printk smashes the kernel */
+	switch (crc_force) {
+	case 3:
+		ax->crcmode  = CRC_MODE_SMACK;
+		printk(KERN_INFO "mkiss: %s: crc mode smack forced.\n",
+		       ax->dev->name);
+		break;
+	case 2:
+		ax->crcmode  = CRC_MODE_FLEX;
+		printk(KERN_INFO "mkiss: %s: crc mode flexnet forced.\n",
+		       ax->dev->name);
+		break;
+	case 1:
+		ax->crcmode  = CRC_MODE_NONE;
+		printk(KERN_INFO "mkiss: %s: crc mode disabled.\n",
+		       ax->dev->name);
+		break;
+	case 0:
+		/* fall through */
+	default:
+		crc_force = 0;
+		printk(KERN_INFO "mkiss: %s: crc mode is auto.\n",
+		       ax->dev->name);
+		ax->crcmode  = CRC_MODE_SMACK_TEST;
+	}
+	ax->crcauto = (crc_force ? 0 : 1);
+
 	netif_start_queue(dev);
 
 	/* Done.  We have linked the TTY line to a channel. */
@@ -903,6 +1017,8 @@ static void __exit mkiss_exit_driver(voi
 
 MODULE_AUTHOR("Ralf Baechle DL5RB <ralf at linux-mips.org>");
 MODULE_DESCRIPTION("KISS driver for AX.25 over TTYs");
+MODULE_PARM(crc_force, "i");
+MODULE_PARM_DESC(crc_force, "crc [0 = auto | 1 = none | 2 = flexnet | 3 = smack]");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS_LDISC(N_AX25);
 
---
0.99.8.GIT


--- NEW FILE 0537-Initialize-the-.owner-field-the-tty_ldisc-structure.txt ---
Subject: [PATCH] Initialize the .owner field the tty_ldisc structure.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1129155061 +0100

If .owner isn't set the module can be unloaded even while still active.

Signed-off-by: Ralf Baechle DL5RB <ralf at linux-mips.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/hamradio/mkiss.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

applies-to: 01455dae41fc5c025341e4d31b8013a2e727e66d
74cfe03f80adc320bde4dd37616354aefe2271aa
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 7961f5b..85d6dc0 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -977,6 +977,7 @@ out:
 }
 
 static struct tty_ldisc ax_ldisc = {
+	.owner		= THIS_MODULE,
 	.magic		= TTY_LDISC_MAGIC,
 	.name		= "mkiss",
 	.open		= mkiss_open,
---
0.99.8.GIT


--- NEW FILE 0565-sb1250-mac-Check-the-actual-setting-for-reporting-hw-checksumming.txt ---
Subject: [PATCH] sb1250-mac: Check the actual setting for reporting hw checksumming.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952224 +0100

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/sb1250-mac.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sb1250-mac.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 307ccb9b815b2b53ad79bb0b0bc5d17a6f39aed0
f567ef935094003ee70ea3fd10f5695d349c0f48
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 7abd55a..0f828da 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -2419,7 +2419,7 @@ static int sbmac_init(struct net_device 
 	if (err)
 		goto out_uninit;
 
-	if (periph_rev >= 2) {
+	if (sc->rx_hw_checksum == ENABLE) {
 		printk(KERN_INFO "%s: enabling TCP rcv checksum\n",
 			sc->sbm_dev->name);
 	}
---
0.99.8.GIT


--- NEW FILE 0566-sb1250-mac-Ensure-16-byte-alignment-of-the-descriptor-ring.txt ---
Subject: [PATCH] sb1250-mac: Ensure 16-byte alignment of the descriptor ring.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952236 +0100

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/sb1250-mac.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletion(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sb1250-mac.c |    9 ++++++++-
 1 files changed, 8 insertions(+), 1 deletions(-)

applies-to: 6259ac64133506c683c9449e6fcb93a490d2f445
04115def6ad7ef51440365b65a7324fcb82d5d1d
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index 0f828da..cb4ea41 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -750,7 +750,14 @@ static void sbdma_initctx(sbmacdma_t *d,
 	d->sbdma_maxdescr = maxdescr;
 	
 	d->sbdma_dscrtable = (sbdmadscr_t *) 
-		kmalloc(d->sbdma_maxdescr*sizeof(sbdmadscr_t), GFP_KERNEL);
+		kmalloc((d->sbdma_maxdescr+1)*sizeof(sbdmadscr_t), GFP_KERNEL);
+
+	/*
+	 * The descriptor table must be aligned to at least 16 bytes or the
+	 * MAC will corrupt it.
+	 */
+	d->sbdma_dscrtable = (sbdmadscr_t *)
+		ALIGN((unsigned long)d->sbdma_dscrtable, sizeof(sbdmadscr_t));
 	
 	memset(d->sbdma_dscrtable,0,d->sbdma_maxdescr*sizeof(sbdmadscr_t));
 	
---
0.99.8.GIT


--- NEW FILE 0567-au1000_eth-Misc-Au1000-net-driver-fixes.txt ---
Subject: [PATCH] au1000_eth: Misc Au1000 net driver fixes.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952241 +0100

 o Add support for DP83847 MII.
 o remove unused variable.
 o Add some initialisations so even an unknown MII won't result in a crash.
 o Correct error message to "no known MIIs found".

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/au1000_eth.c |   13 +++++--------
 1 files changed, 5 insertions(+), 8 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/au1000_eth.c |   13 +++++--------
 1 files changed, 5 insertions(+), 8 deletions(-)

applies-to: 14e7113cad4264ec4cf6f26730437c293f182802
7f553e3db46b36d2662e1118f8b8fdbf086b76df
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index c82b9cd..7850691 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -151,13 +151,6 @@ struct au1000_private *au_macs[NUM_ETH_I
 	SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full | \
 	SUPPORTED_Autoneg
 
-static char *phy_link[] = 
-{	"unknown", 
-	"10Base2", "10BaseT", 
-	"AUI",
-	"100BaseT", "100BaseTX", "100BaseFX"
-};
-
 int bcm_5201_init(struct net_device *dev, int phy_addr)
 {
 	s16 data;
@@ -785,6 +778,7 @@ static struct mii_chip_info {
 	{"Broadcom BCM5201 10/100 BaseT PHY",0x0040,0x6212, &bcm_5201_ops,0},
 	{"Broadcom BCM5221 10/100 BaseT PHY",0x0040,0x61e4, &bcm_5201_ops,0},
 	{"Broadcom BCM5222 10/100 BaseT PHY",0x0040,0x6322, &bcm_5201_ops,1},
+	{"NS DP83847 PHY", 0x2000, 0x5c30, &bcm_5201_ops ,0},
 	{"AMD 79C901 HomePNA PHY",0x0000,0x35c8, &am79c901_ops,0},
 	{"AMD 79C874 10/100 BaseT PHY",0x0022,0x561b, &am79c874_ops,0},
 	{"LSI 80227 10/100 BaseT PHY",0x0016,0xf840, &lsi_80227_ops,0},
@@ -1045,7 +1039,7 @@ found:
 #endif
 
 	if (aup->mii->chip_info == NULL) {
-		printk(KERN_ERR "%s: Au1x No MII transceivers found!\n",
+		printk(KERN_ERR "%s: Au1x No known MII transceivers found!\n",
 				dev->name);
 		return -1;
 	}
@@ -1546,6 +1540,9 @@ au1000_probe(u32 ioaddr, int irq, int po
 		printk(KERN_ERR "%s: out of memory\n", dev->name);
 		goto err_out;
 	}
+	aup->mii->next = NULL;
+	aup->mii->chip_info = NULL;
+	aup->mii->status = 0;
 	aup->mii->mii_control_reg = 0;
 	aup->mii->mii_data_reg = 0;
 
---
0.99.8.GIT


--- NEW FILE 0568-de2104x-Resurrect-Cobalt-support-for-2.6.txt ---
Subject: [PATCH] de2104x: Resurrect Cobalt support for 2.6.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952246 +0100

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/tulip/de2104x.c |    5 +++++
 1 files changed, 5 insertions(+)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/tulip/de2104x.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

applies-to: 72a243aa23c3ff32797b5b2e2269df8575a8d721
bc053d45cb0ca5daeaa69ae9ac43cdea42693f60
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index a22d001..6b8eee8 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -1787,10 +1787,15 @@ static void __init de21041_get_srom_info
 	/* DEC now has a specification but early board makers
 	   just put the address in the first EEPROM locations. */
 	/* This does  memcmp(eedata, eedata+16, 8) */
+
+#ifndef CONFIG_MIPS_COBALT
+
 	for (i = 0; i < 8; i ++)
 		if (ee_data[i] != ee_data[16+i])
 			sa_offset = 20;
 
+#endif
+
 	/* store MAC address */
 	for (i = 0; i < 6; i ++)
 		de->dev->dev_addr[i] = ee_data[i + sa_offset];
---
0.99.8.GIT


--- NEW FILE 0569-sgiseeq-Fix-resource-handling.txt ---
Subject: [PATCH] sgiseeq: Fix resource handling.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952251 +0100

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/sgiseeq.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sgiseeq.c |    9 ++++-----
 1 files changed, 4 insertions(+), 5 deletions(-)

applies-to: 1512d6f1f84744212c6138e02fde5c2f21227f8e
2891439e7378e35534d7eb32f77671dc4d61db4c
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index 9bc3b1c..a9d2e4f 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -493,11 +493,13 @@ static int sgiseeq_close(struct net_devi
 {
 	struct sgiseeq_private *sp = netdev_priv(dev);
 	struct sgiseeq_regs *sregs = sp->sregs;
+	unsigned int irq = dev->irq;
 
 	netif_stop_queue(dev);
 
 	/* Shutdown the Seeq. */
 	reset_hpc3_and_seeq(sp->hregs, sregs);
+	free_irq(irq, dev);
 
 	return 0;
 }
@@ -734,7 +736,7 @@ static int sgiseeq_init(struct hpc3_regs
 	return 0;
 
 err_out_free_page:
-	free_page((unsigned long) sp);
+	free_page((unsigned long) sp->srings);
 err_out_free_dev:
 	kfree(dev);
 
@@ -754,15 +756,12 @@ static void __exit sgiseeq_exit(void)
 {
 	struct net_device *next, *dev;
 	struct sgiseeq_private *sp;
-	int irq;
 
 	for (dev = root_sgiseeq_dev; dev; dev = next) {
 		sp = (struct sgiseeq_private *) netdev_priv(dev);
 		next = sp->next_module;
-		irq = dev->irq;
 		unregister_netdev(dev);
-		free_irq(irq, dev);
-		free_page((unsigned long) sp);
+		free_page((unsigned long) sp->srings);
 		free_netdev(dev);
 	}
 }
---
0.99.8.GIT


--- NEW FILE 0570-sgiseeq-Configure-PIO-and-DMA-timing-requests.txt ---
Subject: [PATCH] sgiseeq: Configure PIO and DMA timing requests.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952256 +0100

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/sgiseeq.c       |   28 ++++++++++++++--------------
 include/asm-mips/sgi/hpc3.h |   40 ++++++++++++++++++++--------------------
 2 files changed, 34 insertions(+), 34 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sgiseeq.c       |   28 ++++++++++++++--------------
 include/asm-mips/sgi/hpc3.h |   40 ++++++++++++++++++++--------------------
 2 files changed, 34 insertions(+), 34 deletions(-)

applies-to: d2cba6b9391f5488f2b6d8d6418b43e9ae3c2969
302a5c4b3d4d6aff7772a4b3431bb772586e6011
diff --git a/drivers/net/sgiseeq.c b/drivers/net/sgiseeq.c
index a9d2e4f..a4614df 100644
--- a/drivers/net/sgiseeq.c
+++ b/drivers/net/sgiseeq.c
@@ -32,8 +32,6 @@
 
 #include "sgiseeq.h"
 
-static char *version = "sgiseeq.c: David S. Miller (dm at engr.sgi.com)\n";
-
 static char *sgiseeqstr = "SGI Seeq8003";
 
 /*
@@ -113,9 +111,9 @@ static struct net_device *root_sgiseeq_d
 
 static inline void hpc3_eth_reset(struct hpc3_ethregs *hregs)
 {
-	hregs->rx_reset = HPC3_ERXRST_CRESET | HPC3_ERXRST_CLRIRQ;
+	hregs->reset = HPC3_ERST_CRESET | HPC3_ERST_CLRIRQ;
 	udelay(20);
-	hregs->rx_reset = 0;
+	hregs->reset = 0;
 }
 
 static inline void reset_hpc3_and_seeq(struct hpc3_ethregs *hregs,
@@ -252,7 +250,6 @@ void sgiseeq_dump_rings(void)
 
 #define TSTAT_INIT_SEEQ (SEEQ_TCMD_IPT|SEEQ_TCMD_I16|SEEQ_TCMD_IC|SEEQ_TCMD_IUF)
 #define TSTAT_INIT_EDLC ((TSTAT_INIT_SEEQ) | SEEQ_TCMD_RB2)
-#define RDMACFG_INIT    (HPC3_ERXDCFG_FRXDC | HPC3_ERXDCFG_FEOP | HPC3_ERXDCFG_FIRQ)
 
 static int init_seeq(struct net_device *dev, struct sgiseeq_private *sp,
 		     struct sgiseeq_regs *sregs)
@@ -274,8 +271,6 @@ static int init_seeq(struct net_device *
 		sregs->tstat = TSTAT_INIT_SEEQ;
 	}
 
-	hregs->rx_dconfig |= RDMACFG_INIT;
-
 	hregs->rx_ndptr = CPHYSADDR(sp->rx_desc);
 	hregs->tx_ndptr = CPHYSADDR(sp->tx_desc);
 
@@ -446,7 +441,7 @@ static irqreturn_t sgiseeq_interrupt(int
 	spin_lock(&sp->tx_lock);
 
 	/* Ack the IRQ and set software state. */
-	hregs->rx_reset = HPC3_ERXRST_CLRIRQ;
+	hregs->reset = HPC3_ERST_CLRIRQ;
 
 	/* Always check for received packets. */
 	sgiseeq_rx(dev, sp, hregs, sregs);
@@ -646,7 +641,7 @@ static inline void setup_rx_ring(struct 
 
 #define ALIGNED(x)  ((((unsigned long)(x)) + 0xf) & ~(0xf))
 
-static int sgiseeq_init(struct hpc3_regs* regs, int irq)
+static int sgiseeq_init(struct hpc3_regs* hpcregs, int irq)
 {
 	struct sgiseeq_init_block *sr;
 	struct sgiseeq_private *sp;
@@ -682,8 +677,8 @@ static int sgiseeq_init(struct hpc3_regs
 	gpriv = sp;
 	gdev = dev;
 #endif
-	sp->sregs = (struct sgiseeq_regs *) &hpc3c0->eth_ext[0];
-	sp->hregs = &hpc3c0->ethregs;
+	sp->sregs = (struct sgiseeq_regs *) &hpcregs->eth_ext[0];
+	sp->hregs = &hpcregs->ethregs;
 	sp->name = sgiseeqstr;
 	sp->mode = SEEQ_RCMD_RBCAST;
 
@@ -700,6 +695,11 @@ static int sgiseeq_init(struct hpc3_regs
 	setup_rx_ring(sp->rx_desc, SEEQ_RX_BUFFERS);
 	setup_tx_ring(sp->tx_desc, SEEQ_TX_BUFFERS);
 
+	/* Setup PIO and DMA transfer timing */
+	sp->hregs->pconfig = 0x161;
+	sp->hregs->dconfig = HPC3_EDCFG_FIRQ | HPC3_EDCFG_FEOP |
+			     HPC3_EDCFG_FRXDC | HPC3_EDCFG_PTO | 0x026;
+
 	/* Reset the chip. */
 	hpc3_eth_reset(sp->hregs);
 
@@ -726,7 +726,7 @@ static int sgiseeq_init(struct hpc3_regs
 		goto err_out_free_page;
 	}
 
-	printk(KERN_INFO "%s: SGI Seeq8003 ", dev->name);
+	printk(KERN_INFO "%s: %s ", dev->name, sgiseeqstr);
 	for (i = 0; i < 6; i++)
 		printk("%2.2x%c", dev->dev_addr[i], i == 5 ? '\n' : ':');
 
@@ -746,8 +746,6 @@ err_out:
 
 static int __init sgiseeq_probe(void)
 {
-	printk(version);
-
 	/* On board adapter on 1st HPC is always present */
 	return sgiseeq_init(hpc3c0, SGI_ENET_IRQ);
 }
@@ -769,4 +767,6 @@ static void __exit sgiseeq_exit(void)
 module_init(sgiseeq_probe);
 module_exit(sgiseeq_exit);
 
+MODULE_DESCRIPTION("SGI Seeq 8003 driver");
+MODULE_AUTHOR("Linux/MIPS Mailing List <linux-mips at linux-mips.org>");
 MODULE_LICENSE("GPL");
diff --git a/include/asm-mips/sgi/hpc3.h b/include/asm-mips/sgi/hpc3.h
index ac3dfc7..fcec52b 100644
--- a/include/asm-mips/sgi/hpc3.h
+++ b/include/asm-mips/sgi/hpc3.h
@@ -128,26 +128,26 @@ struct hpc3_ethregs {
 	volatile u32 rx_gfptr;	/* current GIO fifo ptr */
 	volatile u32 rx_dfptr;	/* current device fifo ptr */
 	u32 _unused1;		/* padding */
-	volatile u32 rx_reset;	/* reset register */
-#define HPC3_ERXRST_CRESET 0x1	/* Reset dma channel and external controller */
-#define HPC3_ERXRST_CLRIRQ 0x2	/* Clear channel interrupt */
-#define HPC3_ERXRST_LBACK  0x4	/* Enable diagnostic loopback mode of Seeq8003 */
-
-	volatile u32 rx_dconfig;	/* DMA configuration register */
-#define HPC3_ERXDCFG_D1    0x0000f /* Cycles to spend in D1 state for PIO */
-#define HPC3_ERXDCFG_D2    0x000f0 /* Cycles to spend in D2 state for PIO */
-#define HPC3_ERXDCFG_D3    0x00f00 /* Cycles to spend in D3 state for PIO */
-#define HPC3_ERXDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
-#define HPC3_ERXDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
-#define HPC3_ERXDCFG_FEOP  0x04000 /* Bad packet marker timeout enable */
-#define HPC3_ERXDCFG_FIRQ  0x08000 /* Another bad packet timeout enable */
-#define HPC3_ERXDCFG_PTO   0x30000 /* Programmed timeout value for above two */
-
-	volatile u32 rx_pconfig;	/* PIO configuration register */
-#define HPC3_ERXPCFG_P1    0x000f /* Cycles to spend in P1 state for PIO */
-#define HPC3_ERXPCFG_P2    0x00f0 /* Cycles to spend in P2 state for PIO */
-#define HPC3_ERXPCFG_P3    0x0f00 /* Cycles to spend in P3 state for PIO */
-#define HPC3_ERXPCFG_TST   0x1000 /* Diagnistic ram test feature bit */
+	volatile u32 reset;	/* reset register */
+#define HPC3_ERST_CRESET 0x1	/* Reset dma channel and external controller */
+#define HPC3_ERST_CLRIRQ 0x2	/* Clear channel interrupt */
+#define HPC3_ERST_LBACK  0x4	/* Enable diagnostic loopback mode of Seeq8003 */
+
+	volatile u32 dconfig;    /* DMA configuration register */
+#define HPC3_EDCFG_D1    0x0000f /* Cycles to spend in D1 state for PIO */
+#define HPC3_EDCFG_D2    0x000f0 /* Cycles to spend in D2 state for PIO */
+#define HPC3_EDCFG_D3    0x00f00 /* Cycles to spend in D3 state for PIO */
+#define HPC3_EDCFG_WCTRL 0x01000 /* Enable writes of desc into ex ctrl port */
+#define HPC3_EDCFG_FRXDC 0x02000 /* Clear eop stat bits upon rxdc, hw seeq fix */
+#define HPC3_EDCFG_FEOP  0x04000 /* Bad packet marker timeout enable */
+#define HPC3_EDCFG_FIRQ  0x08000 /* Another bad packet timeout enable */
+#define HPC3_EDCFG_PTO   0x30000 /* Programmed timeout value for above two */
+
+	volatile u32 pconfig;   /* PIO configuration register */
+#define HPC3_EPCFG_P1    0x000f /* Cycles to spend in P1 state for PIO */
+#define HPC3_EPCFG_P2    0x00f0 /* Cycles to spend in P2 state for PIO */
+#define HPC3_EPCFG_P3    0x0f00 /* Cycles to spend in P3 state for PIO */
+#define HPC3_EPCFG_TST   0x1000 /* Diagnistic ram test feature bit */
 
 	u32 _unused2[0x1000/4 - 8];	/* padding */
 
---
0.99.8.GIT


--- NEW FILE 0571-declance-Convert-to-irqreturn_t.txt ---
Subject: [PATCH] declance: Convert to irqreturn_t.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952261 +0100

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/declance.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/declance.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

applies-to: 0f08e4c1419dae13e86039b53db2271d57bde4e3
da848ec37d9cf9edbe269f8be9b3de52f90d70da
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 521c831..636763b 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -697,12 +697,13 @@ out:
 	spin_unlock(&lp->lock);
 }
 
-static void lance_dma_merr_int(const int irq, void *dev_id,
-				struct pt_regs *regs)
+static irqreturn_t lance_dma_merr_int(const int irq, void *dev_id,
+				      struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) dev_id;
 
 	printk("%s: DMA error\n", dev->name);
+	return IRQ_HANDLED;
 }
 
 static irqreturn_t
---
0.99.8.GIT


--- NEW FILE 0572-declance-Fix-mapping-of-device.txt ---
Subject: [PATCH] declance: Fix mapping of device.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952266 +0100

These should really be addresses obtained with ioremap() or some
bus-specific backend, but for now...

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/declance.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/declance.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

applies-to: 09db5571eca2971dee69423aacf0376e9e4742b8
6684b4e28247f31543edf86ba785aa87e8fa3b39
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 636763b..3af7834 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -237,7 +237,7 @@ struct lance_init_block {
 /*
  * This works *only* for the ring descriptors
  */
-#define LANCE_ADDR(x) (PHYSADDR(x) >> 1)
+#define LANCE_ADDR(x) (CPHYSADDR(x) >> 1)
 
 struct lance_private {
 	struct net_device *next;
@@ -1102,7 +1102,7 @@ static int __init dec_lance_init(const i
 		/* Setup I/O ASIC LANCE DMA.  */
 		lp->dma_irq = dec_interrupt[DEC_IRQ_LANCE_MERR];
 		ioasic_write(IO_REG_LANCE_DMA_P,
-			     PHYSADDR(dev->mem_start) << 3);
+			     CPHYSADDR(dev->mem_start) << 3);
 
 		break;
 
---
0.99.8.GIT


--- NEW FILE 0573-declance-Deal-with-the-bloody-KSEG-vs-CKSEG-horror.txt ---
Subject: [PATCH] declance: Deal with the bloody KSEG vs CKSEG horror...
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952271 +0100

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/declance.c |    2 +-
 1 files changed, 1 insertion(+), 1 deletion(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/declance.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 58c93078ea5a4fe1492172f14d39214ff0066e4e
4569504a36cb6223e2b7ad6530326a1563a8f456
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index 3af7834..b47e3cf 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -1069,7 +1069,7 @@ static int __init dec_lance_init(const i
 		/*
 		 * FIXME: ugly hack!
 		 */
-		dev->mem_start = KSEG1ADDR(0x00020000);
+		dev->mem_start = CKSEG1ADDR(0x00020000);
 		dev->mem_end = dev->mem_start + 0x00020000;
 		dev->irq = dec_interrupt[DEC_IRQ_LANCE];
 		esar_base = system_base + IOASIC_ESAR;
---
0.99.8.GIT


--- NEW FILE 0574-declance-Use-physical-addresses-at-the-interface-level.txt ---
Subject: [PATCH] declance: Use physical addresses at the interface level.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952276 +0100

Use physical addresses at the interface level, letting drivers remap
them as appropriate.

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/declance.c |   26 ++++++++++----------------
 1 files changed, 10 insertions(+), 16 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/declance.c |   26 ++++++++++----------------
 1 files changed, 10 insertions(+), 16 deletions(-)

applies-to: c4693f214012ce7a810a4f82c36d04557af3c2af
36156cdff17a5ab822898d33cd890a6f8287c43c
diff --git a/drivers/net/declance.c b/drivers/net/declance.c
index b47e3cf..f130bda 100644
--- a/drivers/net/declance.c
+++ b/drivers/net/declance.c
@@ -5,7 +5,7 @@
  *
  *      adopted from sunlance.c by Richard van den Berg
  *
- *      Copyright (C) 2002, 2003  Maciej W. Rozycki
+ *      Copyright (C) 2002, 2003, 2005  Maciej W. Rozycki
  *
  *      additional sources:
  *      - PMAD-AA TURBOchannel Ethernet Module Functional Specification,
@@ -57,13 +57,15 @@
 #include <linux/string.h>
 
 #include <asm/addrspace.h>
+#include <asm/system.h>
+
 #include <asm/dec/interrupts.h>
 #include <asm/dec/ioasic.h>
 #include <asm/dec/ioasic_addrs.h>
 #include <asm/dec/kn01.h>
 #include <asm/dec/machtype.h>
+#include <asm/dec/system.h>
 #include <asm/dec/tc.h>
-#include <asm/system.h>
 
 static char version[] __devinitdata =
 "declance.c: v0.009 by Linux MIPS DECstation task force\n";
@@ -79,10 +81,6 @@ MODULE_LICENSE("GPL");
 #define PMAD_LANCE 2
 #define PMAX_LANCE 3
 
-#ifndef CONFIG_TC
-unsigned long system_base;
-unsigned long dmaptr;
-#endif
 
 #define LE_CSR0 0
 #define LE_CSR1 1
@@ -1027,10 +1025,6 @@ static int __init dec_lance_init(const i
 	unsigned long esar_base;
 	unsigned char *esar;
 
-#ifndef CONFIG_TC
-	system_base = KN01_LANCE_BASE;
-#endif
-
 	if (dec_lance_debug && version_printed++ == 0)
 		printk(version);
 
@@ -1063,7 +1057,7 @@ static int __init dec_lance_init(const i
 	switch (type) {
 #ifdef CONFIG_TC
 	case ASIC_LANCE:
-		dev->base_addr = system_base + IOASIC_LANCE;
+		dev->base_addr = CKSEG1ADDR(dec_kn_slot_base + IOASIC_LANCE);
 
 		/* buffer space for the on-board LANCE shared memory */
 		/*
@@ -1072,7 +1066,7 @@ static int __init dec_lance_init(const i
 		dev->mem_start = CKSEG1ADDR(0x00020000);
 		dev->mem_end = dev->mem_start + 0x00020000;
 		dev->irq = dec_interrupt[DEC_IRQ_LANCE];
-		esar_base = system_base + IOASIC_ESAR;
+		esar_base = CKSEG1ADDR(dec_kn_slot_base + IOASIC_ESAR);
 
 		/* Workaround crash with booting KN04 2.1k from Disk */
 		memset((void *)dev->mem_start, 0,
@@ -1109,7 +1103,7 @@ static int __init dec_lance_init(const i
 	case PMAD_LANCE:
 		claim_tc_card(slot);
 
-		dev->mem_start = get_tc_base_addr(slot);
+		dev->mem_start = CKSEG1ADDR(get_tc_base_addr(slot));
 		dev->base_addr = dev->mem_start + 0x100000;
 		dev->irq = get_tc_irq_nr(slot);
 		esar_base = dev->mem_start + 0x1c0002;
@@ -1138,9 +1132,9 @@ static int __init dec_lance_init(const i
 
 	case PMAX_LANCE:
 		dev->irq = dec_interrupt[DEC_IRQ_LANCE];
-		dev->base_addr = KN01_LANCE_BASE;
-		dev->mem_start = KN01_LANCE_BASE + 0x01000000;
-		esar_base = KN01_RTC_BASE + 1;
+		dev->base_addr = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE);
+		dev->mem_start = CKSEG1ADDR(KN01_SLOT_BASE + KN01_LANCE_MEM);
+		esar_base = CKSEG1ADDR(KN01_SLOT_BASE + KN01_ESAR + 1);
 		lp->dma_irq = -1;
 
 		/*
---
0.99.8.GIT


--- NEW FILE 0575-ne-Support-for-RBHMA4500-eval-board.txt ---
Subject: [PATCH] ne: Support for RBHMA4500 eval board.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1128952281 +0100

Support for Toshiba's RBHMA4500 eval board for the TX4938.

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/ne.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/ne.c |   15 +++++++++++++++
 1 files changed, 15 insertions(+), 0 deletions(-)

applies-to: 256f8f15cb24067fd69243759a078f30965d085e
9cc975e00ddb291035bc4d2d49cdc8768ddf1cc3
diff --git a/drivers/net/ne.c b/drivers/net/ne.c
index d209a15..0de8fdd 100644
--- a/drivers/net/ne.c
+++ b/drivers/net/ne.c
@@ -54,6 +54,10 @@ static const char version2[] =
 #include <asm/system.h>
 #include <asm/io.h>
 
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+#include <asm/tx4938/rbtx4938.h>
+#endif
+
 #include "8390.h"
 
 #define DRV_NAME "ne"
@@ -111,6 +115,9 @@ bad_clone_list[] __initdata = {
     {"E-LAN100", "E-LAN200", {0x00, 0x00, 0x5d}}, /* Broken ne1000 clones */
     {"PCM-4823", "PCM-4823", {0x00, 0xc0, 0x6c}}, /* Broken Advantech MoBo */
     {"REALTEK", "RTL8019", {0x00, 0x00, 0xe8}}, /* no-name with Realtek chip */
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+    {"RBHMA4X00-RTL8019", "RBHMA4X00/RTL8019", {0x00, 0x60, 0x0a}},  /* Toshiba built-in */
+#endif
     {"LCS-8834", "LCS-8836", {0x04, 0x04, 0x37}}, /* ShinyNet (SET) */
     {NULL,}
 };
@@ -226,6 +233,10 @@ struct net_device * __init ne_probe(int 
 	sprintf(dev->name, "eth%d", unit);
 	netdev_boot_setup_check(dev);
 
+#ifdef CONFIG_TOSHIBA_RBTX4938
+	dev->base_addr = 0x07f20280;
+	dev->irq = RBTX4938_RTL_8019_IRQ;
+#endif
 	err = do_ne_probe(dev);
 	if (err)
 		goto out;
@@ -506,6 +517,10 @@ static int __init ne_probe1(struct net_d
 	ei_status.name = name;
 	ei_status.tx_start_page = start_page;
 	ei_status.stop_page = stop_page;
+#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938)
+	wordlength = 1;
+#endif
+
 #ifdef CONFIG_PLAT_OAKS32R
 	ei_status.word16 = 0;
 #else
---
0.99.8.GIT


--- NEW FILE 0577-e1000_intr-build-fix.txt ---
Subject: [PATCH] e1000_intr build fix
From: Andrew Morton <akpm at osdl.org>
Date: 1129494734 -0700

drivers/net/e1000/e1000_main.c: In function `e1000_intr':
drivers/net/e1000/e1000_main.c:3156: error: `i' undeclared (first use in this function)
drivers/net/e1000/e1000_main.c:3156: error: (Each undeclared identifier is reported only once
drivers/net/e1000/e1000_main.c:3156: error: for each function it appears in.)

This function is foul.

Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: f3eab7df501b02de7bf09bc6b5c0b62cbabe27af
166d823d397b9f5404648cedfdefe13e10683694
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index dd79449..18847f9 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -3100,7 +3100,7 @@ e1000_intr(int irq, void *data, struct p
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	struct e1000_hw *hw = &adapter->hw;
 	uint32_t icr = E1000_READ_REG(hw, ICR);
-#ifdef CONFIG_E1000_MQ
+#if defined(CONFIG_E1000_NAPI) && defined(CONFIG_E1000_MQ) || !defined(CONFIG_E1000_NAPI)
 	int i;
 #endif
 
---
0.99.8.GIT


--- NEW FILE 0578-s2io-build-fix.txt ---
Subject: [PATCH] s2io build fix
From: Andrew Morton <akpm at osdl.org>
Date: 1129446689 -0700

Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/s2io.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: de09a5a87b3c42925c70228ef2702eab5b891c3f
923833405d8d81b5be036093773d88d87fc7e1bd
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 30fbaf0..d303d16 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2997,7 +2997,7 @@ int s2io_set_swapper(nic_t * sp)
 		 SWAPPER_CTRL_RXF_W_FE |
 		 SWAPPER_CTRL_XMSI_FE |
 		 SWAPPER_CTRL_STATS_FE | SWAPPER_CTRL_STATS_SE);
-	if (nic->intr_type == INTA)
+	if (sp->intr_type == INTA)
 		val64 |= SWAPPER_CTRL_XMSI_SE;
 	writeq(val64, &bar0->swapper_ctrl);
 #else
---
0.99.8.GIT


--- NEW FILE 0580-via-rhine-change-mdelay-to-msleep-and-remove-from-ISR-path.txt ---
Subject: [PATCH] via-rhine: change mdelay to msleep and remove from ISR path
From: John W. Linville <linville at tuxdriver.com>
Date: 1129685462 -0400

Get rid of the mdelay call in rhine_disable_linkmon.  The function
is called from the via-rhine versions of mdio_read and mdio_write.
Those functions are indirectly called from rhine_check_media and
rhine_tx_timeout, both of which can be called in interrupt context.

So, create tx_timeout_task and check_media_task as instances of struct
work_struct inside of rhine_private.  Then, change rhine_tx_timeout to
invoke schedule_work for tx_timeout_task (i.e. rhine_tx_timeout_task),
moving the work to process context.  Also, change rhine_error (invoked
from rhine_interrupt) to invoke schedule_work for check_media_task
(i.e. rhine_check_media_task), which simply calls rhine_check media
in process context.  Finally, add a call to flush_scheduled_work in
rhine_close to avoid any resource conflicts with pending work items.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/via-rhine.c |   34 +++++++++++++++++++++++++++++++---
 1 files changed, 31 insertions(+), 3 deletions(-)

applies-to: 53cef37e2cdfdad21b3b375f57ba6d63ce341252
6ba98d311d0a4ff7dc36d8f435ce60174f4c30ec
diff --git a/drivers/net/via-rhine.c b/drivers/net/via-rhine.c
index e7b4bc3..2418715 100644
--- a/drivers/net/via-rhine.c
+++ b/drivers/net/via-rhine.c
@@ -490,6 +490,8 @@ struct rhine_private {
 	u8 tx_thresh, rx_thresh;
 
 	struct mii_if_info mii_if;
+	struct work_struct tx_timeout_task;
+	struct work_struct check_media_task;
 	void __iomem *base;
 };
 
@@ -497,6 +499,8 @@ static int  mdio_read(struct net_device 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value);
 static int  rhine_open(struct net_device *dev);
 static void rhine_tx_timeout(struct net_device *dev);
+static void rhine_tx_timeout_task(struct net_device *dev);
+static void rhine_check_media_task(struct net_device *dev);
 static int  rhine_start_tx(struct sk_buff *skb, struct net_device *dev);
 static irqreturn_t rhine_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 static void rhine_tx(struct net_device *dev);
@@ -851,6 +855,12 @@ static int __devinit rhine_init_one(stru
 	if (rp->quirks & rqRhineI)
 		dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
 
+	INIT_WORK(&rp->tx_timeout_task,
+		  (void (*)(void *))rhine_tx_timeout_task, dev);
+
+	INIT_WORK(&rp->check_media_task,
+		  (void (*)(void *))rhine_check_media_task, dev);
+
 	/* dev->name not defined before register_netdev()! */
 	rc = register_netdev(dev);
 	if (rc)
@@ -1077,6 +1087,11 @@ static void rhine_check_media(struct net
 		   ioaddr + ChipCmd1);
 }
 
+static void rhine_check_media_task(struct net_device *dev)
+{
+	rhine_check_media(dev, 0);
+}
+
 static void init_registers(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
@@ -1130,8 +1145,8 @@ static void rhine_disable_linkmon(void _
 	if (quirks & rqRhineI) {
 		iowrite8(0x01, ioaddr + MIIRegAddr);	// MII_BMSR
 
-		/* Can be called from ISR. Evil. */
-		mdelay(1);
+		/* Do not call from ISR! */
+		msleep(1);
 
 		/* 0x80 must be set immediately before turning it off */
 		iowrite8(0x80, ioaddr + MIICmd);
@@ -1221,6 +1236,16 @@ static int rhine_open(struct net_device 
 static void rhine_tx_timeout(struct net_device *dev)
 {
 	struct rhine_private *rp = netdev_priv(dev);
+
+	/*
+	 * Move bulk of work outside of interrupt context
+	 */
+	schedule_work(&rp->tx_timeout_task);
+}
+
+static void rhine_tx_timeout_task(struct net_device *dev)
+{
+	struct rhine_private *rp = netdev_priv(dev);
 	void __iomem *ioaddr = rp->base;
 
 	printk(KERN_WARNING "%s: Transmit timed out, status %4.4x, PHY status "
@@ -1626,7 +1651,7 @@ static void rhine_error(struct net_devic
 	spin_lock(&rp->lock);
 
 	if (intr_status & IntrLinkChange)
-		rhine_check_media(dev, 0);
+		schedule_work(&rp->check_media_task);
 	if (intr_status & IntrStatsMax) {
 		rp->stats.rx_crc_errors += ioread16(ioaddr + RxCRCErrs);
 		rp->stats.rx_missed_errors += ioread16(ioaddr + RxMissed);
@@ -1874,6 +1899,9 @@ static int rhine_close(struct net_device
 	spin_unlock_irq(&rp->lock);
 
 	free_irq(rp->pdev->irq, dev);
+
+	flush_scheduled_work();
+
 	free_rbufs(dev);
 	free_tbufs(dev);
 	free_ring(dev);
---
0.99.8.GIT


--- NEW FILE 0581-epic100-fix-counting-of-work_done-in-epic_poll.txt ---
Subject: [PATCH] epic100: fix counting of work_done in epic_poll
From: John W. Linville <linville at tuxdriver.com>
Date: 1129685461 -0400

work_done is overwritten each time through the rx_action loop in
epic_poll.  This screws-up the NAPI accounting if the loop is executed
more than once.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/epic100.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

applies-to: 745daba38635eca9466319f8c8940d1fb3e8ed3c
b7b1d2021452d0a3562807b6a90dfa5124147a79
diff --git a/drivers/net/epic100.c b/drivers/net/epic100.c
index 87f5227..f119ec4 100644
--- a/drivers/net/epic100.c
+++ b/drivers/net/epic100.c
@@ -1334,7 +1334,7 @@ static void epic_rx_err(struct net_devic
 static int epic_poll(struct net_device *dev, int *budget)
 {
 	struct epic_private *ep = dev->priv;
-	int work_done, orig_budget;
+	int work_done = 0, orig_budget;
 	long ioaddr = dev->base_addr;
 
 	orig_budget = (*budget > dev->quota) ? dev->quota : *budget;
@@ -1343,7 +1343,7 @@ rx_action:
 
 	epic_tx(dev, ep);
 
-	work_done = epic_rx(dev, *budget);
+	work_done += epic_rx(dev, *budget);
 
 	epic_rx_err(dev, ep);
 
---
0.99.8.GIT


--- NEW FILE 0585-b44-alternate-allocation-option-for-DMA-descriptors.txt ---
Subject: [PATCH] b44: alternate allocation option for DMA descriptors
From: John W. Linville <linville at tuxdriver.com>
Date: 1129685459 -0400

This is a (final?) hack to support the odd DMA allocation requirements
of the b44 hardware.  The b44 hardware has a 30-bit DMA mask.  On x86,
anything less than a 32-bit DMA mask forces allocations into the 16MB
GFP_DMA range.  The memory there is somewhat limited, often resulting
in an inability to initialize the b44 driver.

This hack uses streaming DMA allocation APIs in order to provide an
alternative in case the GFP_DMA allocation fails.  It is somewhat ugly,
but not much worse than the similar existing hacks to support SKB
allocations in the same driver.  FWIW, I have received positive
feedback on this from several Fedora users.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |  134 ++++++++++++++++++++++++++++++++++++++++++++++++++---
 drivers/net/b44.h |    2 +
 2 files changed, 128 insertions(+), 8 deletions(-)

applies-to: 4f0c2445eb5ddb49c622a9d368a9773bd4fb0f7a
9f38c636ababfb41e58c9ec1e9719492ef7f0479
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index d27e870..282ebd1 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -106,6 +106,29 @@ static int b44_poll(struct net_device *d
 static void b44_poll_controller(struct net_device *dev);
 #endif
 
+static int dma_desc_align_mask;
+static int dma_desc_sync_size;
+
+static inline void b44_sync_dma_desc_for_device(struct pci_dev *pdev,
+                                                dma_addr_t dma_base,
+                                                unsigned long offset,
+                                                enum dma_data_direction dir)
+{
+	dma_sync_single_range_for_device(&pdev->dev, dma_base,
+	                                 offset & dma_desc_align_mask,
+	                                 dma_desc_sync_size, dir);
+}
+
+static inline void b44_sync_dma_desc_for_cpu(struct pci_dev *pdev,
+                                             dma_addr_t dma_base,
+                                             unsigned long offset,
+                                             enum dma_data_direction dir)
+{
+	dma_sync_single_range_for_cpu(&pdev->dev, dma_base,
+	                              offset & dma_desc_align_mask,
+	                              dma_desc_sync_size, dir);
+}
+
 static inline unsigned long br32(const struct b44 *bp, unsigned long reg)
 {
 	return readl(bp->regs + reg);
@@ -668,6 +691,11 @@ static int b44_alloc_rx_skb(struct b44 *
 	dp->ctrl = cpu_to_le32(ctrl);
 	dp->addr = cpu_to_le32((u32) mapping + bp->rx_offset + bp->dma_offset);
 
+	if (bp->flags & B44_FLAG_RX_RING_HACK)
+		b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
+		                             dest_idx * sizeof(dp),
+		                             DMA_BIDIRECTIONAL);
+
 	return RX_PKT_BUF_SZ;
 }
 
@@ -692,6 +720,11 @@ static void b44_recycle_rx(struct b44 *b
 	pci_unmap_addr_set(dest_map, mapping,
 			   pci_unmap_addr(src_map, mapping));
 
+	if (bp->flags & B44_FLAG_RX_RING_HACK)
+		b44_sync_dma_desc_for_cpu(bp->pdev, bp->rx_ring_dma,
+		                          src_idx * sizeof(src_desc),
+		                          DMA_BIDIRECTIONAL);
+
 	ctrl = src_desc->ctrl;
 	if (dest_idx == (B44_RX_RING_SIZE - 1))
 		ctrl |= cpu_to_le32(DESC_CTRL_EOT);
@@ -700,8 +733,14 @@ static void b44_recycle_rx(struct b44 *b
 
 	dest_desc->ctrl = ctrl;
 	dest_desc->addr = src_desc->addr;
+
 	src_map->skb = NULL;
 
+	if (bp->flags & B44_FLAG_RX_RING_HACK)
+		b44_sync_dma_desc_for_device(bp->pdev, bp->rx_ring_dma,
+		                             dest_idx * sizeof(dest_desc),
+		                             DMA_BIDIRECTIONAL);
+
 	pci_dma_sync_single_for_device(bp->pdev, src_desc->addr,
 				       RX_PKT_BUF_SZ,
 				       PCI_DMA_FROMDEVICE);
@@ -959,6 +998,11 @@ static int b44_start_xmit(struct sk_buff
 	bp->tx_ring[entry].ctrl = cpu_to_le32(ctrl);
 	bp->tx_ring[entry].addr = cpu_to_le32((u32) mapping+bp->dma_offset);
 
+	if (bp->flags & B44_FLAG_TX_RING_HACK)
+		b44_sync_dma_desc_for_device(bp->pdev, bp->tx_ring_dma,
+		                             entry * sizeof(bp->tx_ring[0]),
+		                             DMA_TO_DEVICE);
+
 	entry = NEXT_TX(entry);
 
 	bp->tx_prod = entry;
@@ -1064,6 +1108,16 @@ static void b44_init_rings(struct b44 *b
 	memset(bp->rx_ring, 0, B44_RX_RING_BYTES);
 	memset(bp->tx_ring, 0, B44_TX_RING_BYTES);
 
+	if (bp->flags & B44_FLAG_RX_RING_HACK)
+		dma_sync_single_for_device(&bp->pdev->dev, bp->rx_ring_dma,
+		                           DMA_TABLE_BYTES,
+		                           PCI_DMA_BIDIRECTIONAL);
+
+	if (bp->flags & B44_FLAG_TX_RING_HACK)
+		dma_sync_single_for_device(&bp->pdev->dev, bp->tx_ring_dma,
+		                           DMA_TABLE_BYTES,
+		                           PCI_DMA_TODEVICE);
+
 	for (i = 0; i < bp->rx_pending; i++) {
 		if (b44_alloc_rx_skb(bp, -1, i) < 0)
 			break;
@@ -1085,14 +1139,28 @@ static void b44_free_consistent(struct b
 		bp->tx_buffers = NULL;
 	}
 	if (bp->rx_ring) {
-		pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
-				    bp->rx_ring, bp->rx_ring_dma);
+		if (bp->flags & B44_FLAG_RX_RING_HACK) {
+			dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
+				         DMA_TABLE_BYTES,
+				         DMA_BIDIRECTIONAL);
+			kfree(bp->rx_ring);
+		} else
+			pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+					    bp->rx_ring, bp->rx_ring_dma);
 		bp->rx_ring = NULL;
+		bp->flags &= ~B44_FLAG_RX_RING_HACK;
 	}
 	if (bp->tx_ring) {
-		pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
-				    bp->tx_ring, bp->tx_ring_dma);
+		if (bp->flags & B44_FLAG_TX_RING_HACK) {
+			dma_unmap_single(&bp->pdev->dev, bp->tx_ring_dma,
+				         DMA_TABLE_BYTES,
+				         DMA_TO_DEVICE);
+			kfree(bp->tx_ring);
+		} else
+			pci_free_consistent(bp->pdev, DMA_TABLE_BYTES,
+					    bp->tx_ring, bp->tx_ring_dma);
 		bp->tx_ring = NULL;
+		bp->flags &= ~B44_FLAG_TX_RING_HACK;
 	}
 }
 
@@ -1118,12 +1186,56 @@ static int b44_alloc_consistent(struct b
 
 	size = DMA_TABLE_BYTES;
 	bp->rx_ring = pci_alloc_consistent(bp->pdev, size, &bp->rx_ring_dma);
-	if (!bp->rx_ring)
-		goto out_err;
+	if (!bp->rx_ring) {
+		/* Allocation may have failed due to pci_alloc_consistent
+		   insisting on use of GFP_DMA, which is more restrictive
+		   than necessary...  */
+		struct dma_desc *rx_ring;
+		dma_addr_t rx_ring_dma;
+
+		if (!(rx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
+			goto out_err;
+
+		memset(rx_ring, 0, size);
+		rx_ring_dma = dma_map_single(&bp->pdev->dev, rx_ring,
+		                             DMA_TABLE_BYTES,
+		                             DMA_BIDIRECTIONAL);
+
+		if (rx_ring_dma + size > B44_DMA_MASK) {
+			kfree(rx_ring);
+			goto out_err;
+		}
+
+		bp->rx_ring = rx_ring;
+		bp->rx_ring_dma = rx_ring_dma;
+		bp->flags |= B44_FLAG_RX_RING_HACK;
+	}
 
 	bp->tx_ring = pci_alloc_consistent(bp->pdev, size, &bp->tx_ring_dma);
-	if (!bp->tx_ring)
-		goto out_err;
+	if (!bp->tx_ring) {
+		/* Allocation may have failed due to pci_alloc_consistent
+		   insisting on use of GFP_DMA, which is more restrictive
+		   than necessary...  */
+		struct dma_desc *tx_ring;
+		dma_addr_t tx_ring_dma;
+
+		if (!(tx_ring = (struct dma_desc *)kmalloc(size, GFP_KERNEL)))
+			goto out_err;
+
+		memset(tx_ring, 0, size);
+		tx_ring_dma = dma_map_single(&bp->pdev->dev, tx_ring,
+		                             DMA_TABLE_BYTES,
+		                             DMA_TO_DEVICE);
+
+		if (tx_ring_dma + size > B44_DMA_MASK) {
+			kfree(tx_ring);
+			goto out_err;
+		}
+
+		bp->tx_ring = tx_ring;
+		bp->tx_ring_dma = tx_ring_dma;
+		bp->flags |= B44_FLAG_TX_RING_HACK;
+	}
 
 	return 0;
 
@@ -1973,6 +2085,12 @@ static struct pci_driver b44_driver = {
 
 static int __init b44_init(void)
 {
+	unsigned int dma_desc_align_size = dma_get_cache_alignment();
+
+	/* Setup paramaters for syncing RX/TX DMA descriptors */
+	dma_desc_align_mask = ~(dma_desc_align_size - 1);
+	dma_desc_sync_size = max(dma_desc_align_size, sizeof(struct dma_desc));
+
 	return pci_module_init(&b44_driver);
 }
 
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 11c40a2..593cb0a 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -400,6 +400,8 @@ struct b44 {
 #define B44_FLAG_ADV_100HALF	0x04000000
 #define B44_FLAG_ADV_100FULL	0x08000000
 #define B44_FLAG_INTERNAL_PHY	0x10000000
+#define B44_FLAG_RX_RING_HACK	0x20000000
+#define B44_FLAG_TX_RING_HACK	0x40000000
 
 	u32			rx_offset;
 
---
0.99.8.GIT


--- NEW FILE 0586-orinoco-remove-redundance-skb-length-check-before-padding.txt ---
Subject: [PATCH] orinoco: remove redundance skb length check before padding
From: John W. Linville <linville at tuxdriver.com>
Date: 1129685458 -0400

Checking the skb->len value before calling skb_padto is redundant.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco.c |    8 +++-----
 1 files changed, 3 insertions(+), 5 deletions(-)

applies-to: 52a0d64efd7a0f814dd327f2bd983a5c8260b1be
36841c9d02870983c2b08c85d56572c1ff011997
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index da4c5e9..5db2bba 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -492,11 +492,9 @@ static int orinoco_xmit(struct sk_buff *
 
 	/* Check packet length, pad short packets, round up odd length */
 	len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
-	if (skb->len < len) {
-		skb = skb_padto(skb, len);
-		if (skb == NULL)
-			goto fail;
-	}
+	skb = skb_padto(skb, len);
+	if (skb == NULL)
+		goto fail;
 	len -= ETH_HLEN;
 
 	eh = (struct ethhdr *)skb->data;
---
0.99.8.GIT


--- NEW FILE 0587-sundance-remove-if-1-.-block-in-sundance_probe1.txt ---
Subject: [PATCH] sundance: remove if (1) { ... } block in sundance_probe1
From: John W. Linville <linville at tuxdriver.com>
Date: 1129685461 -0400

Remove an if (1) { ... } block in sundance_probe1.  Its purpose seems
to be only to allow for delaring some extra local variables.  But, it also
adds ugly indentation without adding any meaning to the code.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sundance.c |   48 +++++++++++++++++++++++-------------------------
 1 files changed, 23 insertions(+), 25 deletions(-)

applies-to: 367bdf81afd8fdc64147f95cb23493432449c05b
67ec2f805a5260c041b1c3c7a86ecfbc9670db06
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index e148a72..8c4eb11 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -518,6 +518,7 @@ static int __devinit sundance_probe1 (st
 #else
 	int bar = 1;
 #endif
+	int phy, phy_idx = 0;
 
 
 /* when built into the kernel, we only print version if device is found */
@@ -606,33 +607,30 @@ static int __devinit sundance_probe1 (st
 			printk("%2.2x:", dev->dev_addr[i]);
 	printk("%2.2x, IRQ %d.\n", dev->dev_addr[i], irq);
 
-	if (1) {
-		int phy, phy_idx = 0;
-		np->phys[0] = 1;		/* Default setting */
-		np->mii_preamble_required++;
-		for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
-			int mii_status = mdio_read(dev, phy, MII_BMSR);
-			if (mii_status != 0xffff  &&  mii_status != 0x0000) {
-				np->phys[phy_idx++] = phy;
-				np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
-				if ((mii_status & 0x0040) == 0)
-					np->mii_preamble_required++;
-				printk(KERN_INFO "%s: MII PHY found at address %d, status "
-					   "0x%4.4x advertising %4.4x.\n",
-					   dev->name, phy, mii_status, np->mii_if.advertising);
-			}
-		}
-		np->mii_preamble_required--;
-
-		if (phy_idx == 0) {
-			printk(KERN_INFO "%s: No MII transceiver found, aborting.  ASIC status %x\n",
-				   dev->name, ioread32(ioaddr + ASICCtrl));
-			goto err_out_unregister;
-		}
-
-		np->mii_if.phy_id = np->phys[0];
+	np->phys[0] = 1;		/* Default setting */
+	np->mii_preamble_required++;
+	for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
+		int mii_status = mdio_read(dev, phy, MII_BMSR);
+		if (mii_status != 0xffff  &&  mii_status != 0x0000) {
+			np->phys[phy_idx++] = phy;
+			np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
+			if ((mii_status & 0x0040) == 0)
+				np->mii_preamble_required++;
+			printk(KERN_INFO "%s: MII PHY found at address %d, status "
+				   "0x%4.4x advertising %4.4x.\n",
+				   dev->name, phy, mii_status, np->mii_if.advertising);
+		}
+	}
+	np->mii_preamble_required--;
+
+	if (phy_idx == 0) {
+		printk(KERN_INFO "%s: No MII transceiver found, aborting.  ASIC status %x\n",
+			   dev->name, ioread32(ioaddr + ASICCtrl));
+		goto err_out_unregister;
 	}
 
+	np->mii_if.phy_id = np->phys[0];
+
 	/* Parse override configuration */
 	np->an_enable = 1;
 	if (card_idx < MAX_UNITS) {
---
0.99.8.GIT


--- NEW FILE 0588-sundance-expand-reset-mask.txt ---
Subject: [PATCH] sundance: expand reset mask
From: John W. Linville <linville at tuxdriver.com>
Date: 1129685462 -0400

Expand the mask used when reseting the chip to include the GlobalReset
bit.  This fix comes from ICPlus and seems to be required for some
cards.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sundance.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 5cfe4895d39172cdc8afa192932d436322ca3be7
2aa1d82db7a967b748c4b41854c4222cd0484114
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 8c4eb11..d8a7e08 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -691,7 +691,7 @@ static int __devinit sundance_probe1 (st
 	/* Reset the chip to erase previous misconfiguration. */
 	if (netif_msg_hw(np))
 		printk("ASIC Control is %x.\n", ioread32(ioaddr + ASICCtrl));
-	iowrite16(0x007f, ioaddr + ASICCtrl + 2);
+	iowrite16(0x00ff, ioaddr + ASICCtrl + 2);
 	if (netif_msg_hw(np))
 		printk("ASIC Control is now %x.\n", ioread32(ioaddr + ASICCtrl));
 
---
0.99.8.GIT


--- NEW FILE 0589-e1000-build-fix.txt ---
Subject: [PATCH] e1000 build fix
From: Andrew Morton <akpm at osdl.org>
Date: 1129361549 -0700

Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 1f33849dad8fff3a9d287350126794f1cbfa0ef0
c4cfe567b92d5663f98e2f82f28ffc3069fc982f
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 18847f9..40128b9 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -4347,7 +4347,7 @@ e1000_netpoll(struct net_device *netdev)
 	struct e1000_adapter *adapter = netdev_priv(netdev);
 	disable_irq(adapter->pdev->irq);
 	e1000_intr(adapter->pdev->irq, netdev, NULL);
-	e1000_clean_tx_irq(adapter);
+	e1000_clean_tx_irq(adapter, adapter->tx_ring);
 	enable_irq(adapter->pdev->irq);
 }
 #endif
---
0.99.8.GIT


--- NEW FILE 0619-sb1250-mac-Get-rid-of-all-the-funny-SBMAC_WRITECSR-and-SBMAC_READCSR-macros.txt ---
Subject: [PATCH] sb1250-mac: Get rid of all the funny SBMAC_WRITECSR and SBMAC_READCSR macros.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1129732745 +0100

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/sb1250-mac.c |  303 ++++++++++++++++++++---------------------------
 1 files changed, 132 insertions(+), 171 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sb1250-mac.c |  303 ++++++++++++++++++++--------------------------
 1 files changed, 132 insertions(+), 171 deletions(-)

applies-to: 083a81fae56e6f72ec98715caeb9902305195e8f
2039973af59889fea0d14362eae56792cfe8d25a
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index cb4ea41..f7dda6f 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -118,8 +118,6 @@ MODULE_PARM_DESC(int_timeout, "Timeout v
  ********************************************************************* */
 
 
-typedef unsigned long sbmac_port_t;
-
 typedef enum { sbmac_speed_auto, sbmac_speed_10,
 	       sbmac_speed_100, sbmac_speed_1000 } sbmac_speed_t;
 
@@ -144,10 +142,6 @@ typedef enum { sbmac_state_uninit, sbmac
 
 #define NUMCACHEBLKS(x) (((x)+SMP_CACHE_BYTES-1)/SMP_CACHE_BYTES)
 
-#define SBMAC_READCSR(t)	__raw_readq((unsigned long)t)
-#define SBMAC_WRITECSR(t,v)	__raw_writeq(v, (unsigned long)t)
- 
-
 #define SBMAC_MAX_TXDESCR	32
 #define SBMAC_MAX_RXDESCR	32
 
@@ -187,11 +181,11 @@ typedef struct sbmacdma_s {
 	int		 sbdma_int_timeout; /* # usec rx/tx interrupt */
 #endif
 
-	sbmac_port_t     sbdma_config0;	/* DMA config register 0 */
-	sbmac_port_t     sbdma_config1;	/* DMA config register 1 */
-	sbmac_port_t     sbdma_dscrbase;	/* Descriptor base address */
-	sbmac_port_t     sbdma_dscrcnt;     /* Descriptor count register */
-	sbmac_port_t     sbdma_curdscr;	/* current descriptor address */
+	volatile void __iomem *sbdma_config0;	/* DMA config register 0 */
+	volatile void __iomem *sbdma_config1;	/* DMA config register 1 */
+	volatile void __iomem *sbdma_dscrbase;	/* Descriptor base address */
+	volatile void __iomem *sbdma_dscrcnt;     /* Descriptor count register */
+	volatile void __iomem *sbdma_curdscr;	/* current descriptor address */
 	
 	/*
 	 * This stuff is for maintenance of the ring
@@ -236,17 +230,17 @@ struct sbmac_softc {
 	 * Controller-specific things
 	 */
 	
-	unsigned long	sbm_base;          /* MAC's base address */
+	volatile void __iomem *sbm_base;          /* MAC's base address */
 	sbmac_state_t    sbm_state;         /* current state */
 	
-	sbmac_port_t     sbm_macenable;	/* MAC Enable Register */
-	sbmac_port_t     sbm_maccfg;	/* MAC Configuration Register */
-	sbmac_port_t     sbm_fifocfg;	/* FIFO configuration register */
-	sbmac_port_t     sbm_framecfg;	/* Frame configuration register */
-	sbmac_port_t     sbm_rxfilter;	/* receive filter register */
-	sbmac_port_t     sbm_isr;		/* Interrupt status register */
-	sbmac_port_t     sbm_imr;		/* Interrupt mask register */
-	sbmac_port_t     sbm_mdio;		/* MDIO register */
+	volatile void __iomem	*sbm_macenable;	/* MAC Enable Register */
+	volatile void __iomem	*sbm_maccfg;	/* MAC Configuration Register */
+	volatile void __iomem	*sbm_fifocfg;	/* FIFO configuration register */
+	volatile void __iomem	*sbm_framecfg;	/* Frame configuration register */
+	volatile void __iomem	*sbm_rxfilter;	/* receive filter register */
+	volatile void __iomem	*sbm_isr;	/* Interrupt status register */
+	volatile void __iomem	*sbm_imr;	/* Interrupt mask register */
+	volatile void __iomem	*sbm_mdio;	/* MDIO register */
 	
 	sbmac_speed_t    sbm_speed;		/* current speed */
 	sbmac_duplex_t   sbm_duplex;	/* current duplex */
@@ -467,15 +461,15 @@ static void sbmac_mii_sync(struct sbmac_
 	uint64_t bits;
 	int mac_mdio_genc;
 
-	mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
+	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
 	
 	bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT;
 	
-	SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+	__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
 	
 	for (cnt = 0; cnt < 32; cnt++) {
-		SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC | mac_mdio_genc);
-		SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+		__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
 	}
 }
 
@@ -498,10 +492,10 @@ static void sbmac_mii_senddata(struct sb
 	unsigned int curmask;
 	int mac_mdio_genc;
 
-	mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
+	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
 	
 	bits = M_MAC_MDIO_DIR_OUTPUT;
-	SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+	__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
 	
 	curmask = 1 << (bitcnt - 1);
 	
@@ -509,9 +503,9 @@ static void sbmac_mii_senddata(struct sb
 		if (data & curmask)
 			bits |= M_MAC_MDIO_OUT;
 		else bits &= ~M_MAC_MDIO_OUT;
-		SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
-		SBMAC_WRITECSR(s->sbm_mdio,bits | M_MAC_MDC | mac_mdio_genc);
-		SBMAC_WRITECSR(s->sbm_mdio,bits | mac_mdio_genc);
+		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
+		__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
 		curmask >>= 1;
 	}
 }
@@ -559,33 +553,31 @@ static unsigned int sbmac_mii_read(struc
 	sbmac_mii_senddata(s,phyaddr, 5);
 	sbmac_mii_senddata(s,regidx, 5);
 	
-	mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
+	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
 	
 	/* 
 	 * Switch the port around without a clock transition.
 	 */
-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
 	
 	/*
 	 * Send out a clock pulse to signal we want the status
 	 */
 	
-	SBMAC_WRITECSR(s->sbm_mdio,
-		       M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc);
-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
 	
 	/* 
 	 * If an error occurred, the PHY will signal '1' back
 	 */
-	error = SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN;
+	error = __raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN;
 	
 	/* 
 	 * Issue an 'idle' clock pulse, but keep the direction
 	 * the same.
 	 */
-	SBMAC_WRITECSR(s->sbm_mdio,
-		       M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc);
-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+	__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
 	
 	regval = 0;
 	
@@ -593,18 +585,16 @@ static unsigned int sbmac_mii_read(struc
 		regval <<= 1;
 		
 		if (error == 0) {
-			if (SBMAC_READCSR(s->sbm_mdio) & M_MAC_MDIO_IN)
+			if (__raw_readq(s->sbm_mdio) & M_MAC_MDIO_IN)
 				regval |= 1;
 		}
 		
-		SBMAC_WRITECSR(s->sbm_mdio,
-			       M_MAC_MDIO_DIR_INPUT|M_MAC_MDC | mac_mdio_genc);
-		SBMAC_WRITECSR(s->sbm_mdio,
-			       M_MAC_MDIO_DIR_INPUT | mac_mdio_genc);
+		__raw_writeq(M_MAC_MDIO_DIR_INPUT|M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
+		__raw_writeq(M_MAC_MDIO_DIR_INPUT | mac_mdio_genc, s->sbm_mdio);
 	}
 	
 	/* Switch back to output */
-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc);
+	__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
 	
 	if (error == 0)
 		return regval;
@@ -641,9 +631,9 @@ static void sbmac_mii_write(struct sbmac
 	sbmac_mii_senddata(s,MII_COMMAND_ACK,2);
 	sbmac_mii_senddata(s,regval,16);
 
-	mac_mdio_genc = SBMAC_READCSR(s->sbm_mdio) & M_MAC_GENC;
+	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
 
-	SBMAC_WRITECSR(s->sbm_mdio,M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc);
+	__raw_writeq(M_MAC_MDIO_DIR_OUTPUT | mac_mdio_genc, s->sbm_mdio);
 }
 
 
@@ -685,48 +675,27 @@ static void sbdma_initctx(sbmacdma_t *d,
 	s->sbe_idx =(s->sbm_base - A_MAC_BASE_0)/MAC_SPACING;
 #endif
 
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)), 0);
-	SBMAC_WRITECSR(IOADDR(
-	A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)), 0);
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BYTES)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_COLLISIONS)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_LATE_COL)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_EX_COL)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_FCS_ERROR)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_ABORT)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_BAD)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_GOOD)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_RUNT)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_TX_OVERSIZE)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BYTES)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_MCAST)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BCAST)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_BAD)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_GOOD)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_RUNT)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_OVERSIZE)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_FCS_ERROR)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_LENGTH_ERROR)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_CODE_ERROR)));
+	__raw_writeq(0, IOADDR(A_MAC_REGISTER(s->sbe_idx, R_MAC_RMON_RX_ALIGN_ERROR)));
 
 	/* 
 	 * initialize register pointers 
@@ -814,22 +783,19 @@ static void sbdma_channel_start(sbmacdma
 	 */
 	
 #ifdef CONFIG_SBMAC_COALESCE
-	SBMAC_WRITECSR(d->sbdma_config1,
-		       V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) |
-		       0);
-	SBMAC_WRITECSR(d->sbdma_config0,
-		       M_DMA_EOP_INT_EN |
+	__raw_writeq(V_DMA_INT_TIMEOUT(d->sbdma_int_timeout) |
+		       0, d->sbdma_config1);
+	__raw_writeq(M_DMA_EOP_INT_EN |
 		       V_DMA_RINGSZ(d->sbdma_maxdescr) |
 		       V_DMA_INT_PKTCNT(d->sbdma_int_pktcnt) |
-		       0);
+		       0, d->sbdma_config0);
 #else
-	SBMAC_WRITECSR(d->sbdma_config1,0);
-	SBMAC_WRITECSR(d->sbdma_config0,
-		       V_DMA_RINGSZ(d->sbdma_maxdescr) |
-		       0);
+	__raw_writeq(0, d->sbdma_config1);
+	__raw_writeq(V_DMA_RINGSZ(d->sbdma_maxdescr) |
+		       0, d->sbdma_config0);
 #endif
 
-	SBMAC_WRITECSR(d->sbdma_dscrbase,d->sbdma_dscrtable_phys);
+	__raw_writeq(d->sbdma_dscrtable_phys, d->sbdma_dscrbase);
 
 	/*
 	 * Initialize ring pointers
@@ -857,18 +823,18 @@ static void sbdma_channel_stop(sbmacdma_
 	 * Turn off the DMA channel
 	 */
 	
-	SBMAC_WRITECSR(d->sbdma_config1,0);
+	__raw_writeq(0, d->sbdma_config1);
 	
-	SBMAC_WRITECSR(d->sbdma_dscrbase,0);
+	__raw_writeq(0, d->sbdma_dscrbase);
 	
-	SBMAC_WRITECSR(d->sbdma_config0,0);
+	__raw_writeq(0, d->sbdma_config0);
 	
 	/*
 	 * Zero ring pointers
 	 */
 	
-	d->sbdma_addptr = 0;
-	d->sbdma_remptr = 0;
+	d->sbdma_addptr = NULL;
+	d->sbdma_remptr = NULL;
 }
 
 static void sbdma_align_skb(struct sk_buff *skb,int power2,int offset)
@@ -971,8 +937,7 @@ static int sbdma_add_rcvbuffer(sbmacdma_
 	 * Do not interrupt per DMA transfer.
 	 */
 	dsc->dscr_a = virt_to_phys(sb_new->data) |
-		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
-		0;
+		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) | 0;
 #else
 	dsc->dscr_a = virt_to_phys(sb_new->data) |
 		V_DMA_DSCRA_A_SIZE(NUMCACHEBLKS(pktsize+ETHER_ALIGN)) |
@@ -998,7 +963,7 @@ static int sbdma_add_rcvbuffer(sbmacdma_
 	 * Give the buffer to the DMA engine.
 	 */
 	
-	SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
+	__raw_writeq(1, d->sbdma_dscrcnt);
 	
 	return 0;					/* we did it */
 }
@@ -1088,7 +1053,7 @@ static int sbdma_add_txbuffer(sbmacdma_t
 	 * Give the buffer to the DMA engine.
 	 */
 	
-	SBMAC_WRITECSR(d->sbdma_dscrcnt,1);
+	__raw_writeq(1, d->sbdma_dscrcnt);
 	
 	return 0;					/* we did it */
 }
@@ -1184,7 +1149,7 @@ static void sbdma_rx_process(struct sbma
 		 */
 		
 		curidx = d->sbdma_remptr - d->sbdma_dscrtable;
-		hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+		hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
 				d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
 		
 		/*
@@ -1311,7 +1276,7 @@ static void sbdma_tx_process(struct sbma
 		 */
 		
 		curidx = d->sbdma_remptr - d->sbdma_dscrtable;
-		hwidx = (int) (((SBMAC_READCSR(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
+		hwidx = (int) (((__raw_readq(d->sbdma_curdscr) & M_DMA_CURDSCR_ADDR) -
 				d->sbdma_dscrtable_phys) / sizeof(sbdmadscr_t));
 
 		/*
@@ -1467,7 +1432,7 @@ static void sbmac_uninitctx(struct sbmac
 static void sbmac_channel_start(struct sbmac_softc *s)
 {
 	uint64_t reg;
-	sbmac_port_t port;
+	volatile void __iomem *port;
 	uint64_t cfg,fifo,framecfg;
 	int idx, th_value;
 	
@@ -1482,13 +1447,13 @@ static void sbmac_channel_start(struct s
 	 * Bring the controller out of reset, but leave it off.
 	 */
 	
-	SBMAC_WRITECSR(s->sbm_macenable,0);
+	__raw_writeq(0, s->sbm_macenable);
 	
 	/*
 	 * Ignore all received packets
 	 */
 	
-	SBMAC_WRITECSR(s->sbm_rxfilter,0);
+	__raw_writeq(0, s->sbm_rxfilter);
 	
 	/* 
 	 * Calculate values for various control registers.
@@ -1532,7 +1497,7 @@ static void sbmac_channel_start(struct s
 	
 	port = s->sbm_base + R_MAC_HASH_BASE;
 	for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
-		SBMAC_WRITECSR(port,0);
+		__raw_writeq(0, port);
 		port += sizeof(uint64_t);
 	}
 	
@@ -1542,7 +1507,7 @@ static void sbmac_channel_start(struct s
 	
 	port = s->sbm_base + R_MAC_ADDR_BASE;
 	for (idx = 0; idx < MAC_ADDR_COUNT; idx++) {
-		SBMAC_WRITECSR(port,0);
+		__raw_writeq(0, port);
 		port += sizeof(uint64_t);
 	}
 	
@@ -1552,14 +1517,14 @@ static void sbmac_channel_start(struct s
 	
 	port = s->sbm_base + R_MAC_CHUP0_BASE;
 	for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
-		SBMAC_WRITECSR(port,0);
+		__raw_writeq(0, port);
 		port += sizeof(uint64_t);
 	}
 
 
 	port = s->sbm_base + R_MAC_CHLO0_BASE;
 	for (idx = 0; idx < MAC_CHMAP_COUNT; idx++) {
-		SBMAC_WRITECSR(port,0);
+		__raw_writeq(0, port);
 		port += sizeof(uint64_t);
 	}
 	
@@ -1571,7 +1536,7 @@ static void sbmac_channel_start(struct s
 	reg = sbmac_addr2reg(s->sbm_hwaddr);
 	
 	port = s->sbm_base + R_MAC_ADDR_BASE;
-	SBMAC_WRITECSR(port,reg);
+	__raw_writeq(reg, port);
 	port = s->sbm_base + R_MAC_ETHERNET_ADDR;
 
 #ifdef CONFIG_SB1_PASS_1_WORKAROUNDS
@@ -1580,9 +1545,9 @@ static void sbmac_channel_start(struct s
 	 * destination address in the R_MAC_ETHERNET_ADDR register.
 	 * Set the value to zero.
 	 */
-	SBMAC_WRITECSR(port,0);
+	__raw_writeq(0, port);
 #else
-	SBMAC_WRITECSR(port,reg);
+	__raw_writeq(reg, port);
 #endif
 	
 	/*
@@ -1590,11 +1555,11 @@ static void sbmac_channel_start(struct s
 	 * to the various config registers
 	 */
 	
-	SBMAC_WRITECSR(s->sbm_rxfilter,0);
-	SBMAC_WRITECSR(s->sbm_imr,0);
-	SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
-	SBMAC_WRITECSR(s->sbm_fifocfg,fifo);
-	SBMAC_WRITECSR(s->sbm_maccfg,cfg);
+	__raw_writeq(0, s->sbm_rxfilter);
+	__raw_writeq(0, s->sbm_imr);
+	__raw_writeq(framecfg, s->sbm_framecfg);
+	__raw_writeq(fifo, s->sbm_fifocfg);
+	__raw_writeq(cfg, s->sbm_maccfg);
 	
 	/*
 	 * Initialize DMA channels (rings should be ok now)
@@ -1620,11 +1585,10 @@ static void sbmac_channel_start(struct s
 	 * Turn on the rest of the bits in the enable register
 	 */      
 	
-	SBMAC_WRITECSR(s->sbm_macenable,
-		       M_MAC_RXDMA_EN0 |
+	__raw_writeq(M_MAC_RXDMA_EN0 |
 		       M_MAC_TXDMA_EN0 |
 		       M_MAC_RX_ENABLE |
-		       M_MAC_TX_ENABLE);
+		       M_MAC_TX_ENABLE, s->sbm_macenable);
 	
 	
 
@@ -1633,23 +1597,21 @@ static void sbmac_channel_start(struct s
 	/*
 	 * Accept any TX interrupt and EOP count/timer RX interrupts on ch 0
 	 */
-	SBMAC_WRITECSR(s->sbm_imr,
-		       ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
-		       ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0));
+	__raw_writeq(((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_TX_CH0) |
+		       ((M_MAC_INT_EOP_COUNT | M_MAC_INT_EOP_TIMER) << S_MAC_RX_CH0), s->sbm_imr);
 #else
 	/*
 	 * Accept any kind of interrupt on TX and RX DMA channel 0
 	 */
-	SBMAC_WRITECSR(s->sbm_imr,
-		       (M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
-		       (M_MAC_INT_CHANNEL << S_MAC_RX_CH0));
+	__raw_writeq((M_MAC_INT_CHANNEL << S_MAC_TX_CH0) |
+		       (M_MAC_INT_CHANNEL << S_MAC_RX_CH0), s->sbm_imr);
 #endif
 	
 	/* 
 	 * Enable receiving unicasts and broadcasts 
 	 */
 	
-	SBMAC_WRITECSR(s->sbm_rxfilter,M_MAC_UCAST_EN | M_MAC_BCAST_EN);
+	__raw_writeq(M_MAC_UCAST_EN | M_MAC_BCAST_EN, s->sbm_rxfilter);
 	
 	/*
 	 * we're running now. 
@@ -1695,8 +1657,8 @@ static void sbmac_channel_stop(struct sb
 	
 	/* don't accept any packets, disable all interrupts */
 	
-	SBMAC_WRITECSR(s->sbm_rxfilter,0);
-	SBMAC_WRITECSR(s->sbm_imr,0);
+	__raw_writeq(0, s->sbm_rxfilter);
+	__raw_writeq(0, s->sbm_imr);
 	
 	/* Turn off ticker */
 	
@@ -1704,7 +1666,7 @@ static void sbmac_channel_stop(struct sb
 	
 	/* turn off receiver and transmitter */
 	
-	SBMAC_WRITECSR(s->sbm_macenable,0);
+	__raw_writeq(0, s->sbm_macenable);
 	
 	/* We're stopped now. */
 	
@@ -1788,14 +1750,14 @@ static void sbmac_promiscuous_mode(struc
 		return;
 	
 	if (onoff) {
-		reg = SBMAC_READCSR(sc->sbm_rxfilter);
+		reg = __raw_readq(sc->sbm_rxfilter);
 		reg |= M_MAC_ALLPKT_EN;
-		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+		__raw_writeq(reg, sc->sbm_rxfilter);
 	}	
 	else {
-		reg = SBMAC_READCSR(sc->sbm_rxfilter);
+		reg = __raw_readq(sc->sbm_rxfilter);
 		reg &= ~M_MAC_ALLPKT_EN;
-		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+		__raw_writeq(reg, sc->sbm_rxfilter);
 	}
 }
 
@@ -1816,9 +1778,9 @@ static void sbmac_set_iphdr_offset(struc
 	uint64_t reg;
 	
 	/* Hard code the off set to 15 for now */
-	reg = SBMAC_READCSR(sc->sbm_rxfilter);
+	reg = __raw_readq(sc->sbm_rxfilter);
 	reg &= ~M_MAC_IPHDR_OFFSET | V_MAC_IPHDR_OFFSET(15);
-	SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+	__raw_writeq(reg, sc->sbm_rxfilter);
 	
 	/* read system identification to determine revision */
 	if (periph_rev >= 2) {
@@ -1897,8 +1859,8 @@ static int sbmac_set_speed(struct sbmac_
 	 * Read current register values 
 	 */
 	
-	cfg = SBMAC_READCSR(s->sbm_maccfg);
-	framecfg = SBMAC_READCSR(s->sbm_framecfg);
+	cfg = __raw_readq(s->sbm_maccfg);
+	framecfg = __raw_readq(s->sbm_framecfg);
 	
 	/*
 	 * Mask out the stuff we want to change
@@ -1947,8 +1909,8 @@ static int sbmac_set_speed(struct sbmac_
 	 * Send the bits back to the hardware 
 	 */
 	
-	SBMAC_WRITECSR(s->sbm_framecfg,framecfg);
-	SBMAC_WRITECSR(s->sbm_maccfg,cfg);
+	__raw_writeq(framecfg, s->sbm_framecfg);
+	__raw_writeq(cfg, s->sbm_maccfg);
 	
 	return 1;
 }
@@ -1987,7 +1949,7 @@ static int sbmac_set_duplex(struct sbmac
 	 * Read current register values 
 	 */
 	
-	cfg = SBMAC_READCSR(s->sbm_maccfg);
+	cfg = __raw_readq(s->sbm_maccfg);
 	
 	/*
 	 * Mask off the stuff we're about to change
@@ -2046,7 +2008,7 @@ static int sbmac_set_duplex(struct sbmac
 	 * Send the bits back to the hardware 
 	 */
 	
-	SBMAC_WRITECSR(s->sbm_maccfg,cfg);
+	__raw_writeq(cfg, s->sbm_maccfg);
 	
 	return 1;
 }
@@ -2079,7 +2041,7 @@ static irqreturn_t sbmac_intr(int irq,vo
 		 * register, except for counter addr)
 		 */
 		
-		isr = SBMAC_READCSR(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
+		isr = __raw_readq(sc->sbm_isr) & ~M_MAC_COUNTER_ADDR;
 		
 		if (isr == 0)
 			break;
@@ -2180,7 +2142,7 @@ static int sbmac_start_tx(struct sk_buff
 static void sbmac_setmulti(struct sbmac_softc *sc)
 {
 	uint64_t reg;
-	sbmac_port_t port;
+	volatile void __iomem *port;
 	int idx;
 	struct dev_mc_list *mclist;
 	struct net_device *dev = sc->sbm_dev;
@@ -2193,30 +2155,30 @@ static void sbmac_setmulti(struct sbmac_
 	
 	for (idx = 1; idx < MAC_ADDR_COUNT; idx++) {
 		port = sc->sbm_base + R_MAC_ADDR_BASE+(idx*sizeof(uint64_t));
-		SBMAC_WRITECSR(port,0);	
+		__raw_writeq(0, port);
 	}
 	
 	for (idx = 0; idx < MAC_HASH_COUNT; idx++) {
 		port = sc->sbm_base + R_MAC_HASH_BASE+(idx*sizeof(uint64_t));
-		SBMAC_WRITECSR(port,0);	
+		__raw_writeq(0, port);
 	}
 	
 	/*
 	 * Clear the filter to say we don't want any multicasts.
 	 */
 	
-	reg = SBMAC_READCSR(sc->sbm_rxfilter);
+	reg = __raw_readq(sc->sbm_rxfilter);
 	reg &= ~(M_MAC_MCAST_INV | M_MAC_MCAST_EN);
-	SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+	__raw_writeq(reg, sc->sbm_rxfilter);
 	
 	if (dev->flags & IFF_ALLMULTI) {
 		/* 
 		 * Enable ALL multicasts.  Do this by inverting the 
 		 * multicast enable bit. 
 		 */
-		reg = SBMAC_READCSR(sc->sbm_rxfilter);
+		reg = __raw_readq(sc->sbm_rxfilter);
 		reg |= (M_MAC_MCAST_INV | M_MAC_MCAST_EN);
-		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+		__raw_writeq(reg, sc->sbm_rxfilter);
 		return;
 	}
 	
@@ -2235,7 +2197,7 @@ static void sbmac_setmulti(struct sbmac_
 	while (mclist && (idx < MAC_ADDR_COUNT)) {
 		reg = sbmac_addr2reg(mclist->dmi_addr);
 		port = sc->sbm_base + R_MAC_ADDR_BASE+(idx * sizeof(uint64_t));
-		SBMAC_WRITECSR(port,reg);
+		__raw_writeq(reg, port);
 		idx++;
 		mclist = mclist->next;
 	}
@@ -2246,9 +2208,9 @@ static void sbmac_setmulti(struct sbmac_
 	 */
 	
 	if (idx > 1) {
-		reg = SBMAC_READCSR(sc->sbm_rxfilter);
+		reg = __raw_readq(sc->sbm_rxfilter);
 		reg |= M_MAC_MCAST_EN;
-		SBMAC_WRITECSR(sc->sbm_rxfilter,reg);
+		__raw_writeq(reg, sc->sbm_rxfilter);
 	}
 }
 
@@ -2377,8 +2339,8 @@ static int sbmac_init(struct net_device 
 	 * for us in the ethernet address register for each mac.
 	 */
 	
-	ea_reg = SBMAC_READCSR(sc->sbm_base + R_MAC_ETHERNET_ADDR);
-	SBMAC_WRITECSR(sc->sbm_base + R_MAC_ETHERNET_ADDR, 0);
+	ea_reg = __raw_readq(sc->sbm_base + R_MAC_ETHERNET_ADDR);
+	__raw_writeq(0, sc->sbm_base + R_MAC_ETHERNET_ADDR);
 	for (i = 0; i < 6; i++) {
 		eaddr[i] = (uint8_t) (ea_reg & 0xFF);
 		ea_reg >>= 8;
@@ -2465,7 +2427,7 @@ static int sbmac_open(struct net_device 
 	 * yet)
 	 */
 
-	SBMAC_READCSR(sc->sbm_isr);
+	__raw_readq(sc->sbm_isr);
 	if (request_irq(dev->irq, &sbmac_intr, SA_SHIRQ, dev->name, dev))
 		return -EBUSY;
 
@@ -2800,13 +2762,13 @@ sbmac_setup_hwaddr(int chan,char *addr)
 {
 	uint8_t eaddr[6];
 	uint64_t val;
-	sbmac_port_t port;
+	unsigned long port;
 
 	port = A_MAC_CHANNEL_BASE(chan);
 	sbmac_parse_hwaddr(addr,eaddr);
 	val = sbmac_addr2reg(eaddr);
-	SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),val);
-	val = SBMAC_READCSR(IOADDR(port+R_MAC_ETHERNET_ADDR));
+	__raw_writeq(val, IOADDR(port+R_MAC_ETHERNET_ADDR));
+	val = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
 }
 #endif
 
@@ -2817,7 +2779,7 @@ sbmac_init_module(void)
 {
 	int idx;
 	struct net_device *dev;
-	sbmac_port_t port;
+	unsigned long port;
 	int chip_max_units;
 	
 	/*
@@ -2871,7 +2833,7 @@ sbmac_init_module(void)
 		 * If we find a zero, skip this MAC.
 		 */
 
-		sbmac_orig_hwaddr[idx] = SBMAC_READCSR(IOADDR(port+R_MAC_ETHERNET_ADDR));
+		sbmac_orig_hwaddr[idx] = __raw_readq(IOADDR(port+R_MAC_ETHERNET_ADDR));
 		if (sbmac_orig_hwaddr[idx] == 0) {
 			printk(KERN_DEBUG "sbmac: not configuring MAC at "
 			       "%lx\n", port);
@@ -2893,8 +2855,7 @@ sbmac_init_module(void)
 		dev->mem_end = 0;
 		if (sbmac_init(dev, idx)) {
 			port = A_MAC_CHANNEL_BASE(idx);
-			SBMAC_WRITECSR(IOADDR(port+R_MAC_ETHERNET_ADDR),
-				       sbmac_orig_hwaddr[idx]);
+			__raw_writeq(sbmac_orig_hwaddr[idx], IOADDR(port+R_MAC_ETHERNET_ADDR));
 			free_netdev(dev);
 			continue;
 		}
---
0.99.8.GIT


--- NEW FILE 0620-sb1250-mac-Whitespace-cleanup.txt ---
Subject: [PATCH] sb1250-mac: Whitespace cleanup.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1129732802 +0100

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>

 drivers/net/sb1250-mac.c | 1030 +++++++++++++++++++++++------------------------
 1 files changed, 515 insertions(+), 515 deletions(-)
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sb1250-mac.c | 1030 +++++++++++++++++++++++-----------------------
 1 files changed, 515 insertions(+), 515 deletions(-)

applies-to: 589acab53824f20a4cdd4cd5052ec9c6dc410abf
74b0247fbd4b6ed1693a420d85cf50267d840ef4
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index f7dda6f..d4c8ecd 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -10,7 +10,7 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
@@ -127,7 +127,7 @@ typedef enum { sbmac_duplex_auto, sbmac_
 typedef enum { sbmac_fc_auto, sbmac_fc_disabled, sbmac_fc_frame,
 	       sbmac_fc_collision, sbmac_fc_carrier } sbmac_fc_t;
 
-typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on, 
+typedef enum { sbmac_state_uninit, sbmac_state_off, sbmac_state_on,
 	       sbmac_state_broken } sbmac_state_t;
 
 
@@ -147,8 +147,8 @@ typedef enum { sbmac_state_uninit, sbmac
 
 #define ETHER_ALIGN	2
 #define ETHER_ADDR_LEN	6
-#define ENET_PACKET_SIZE	1518 
-/*#define ENET_PACKET_SIZE	9216 */ 
+#define ENET_PACKET_SIZE	1518
+/*#define ENET_PACKET_SIZE	9216 */
 
 /**********************************************************************
  *  DMA Descriptor structure
@@ -166,12 +166,12 @@ typedef unsigned long paddr_t;
  ********************************************************************* */
 
 typedef struct sbmacdma_s {
-	
-	/* 
+
+	/*
 	 * This stuff is used to identify the channel and the registers
 	 * associated with it.
 	 */
-	
+
 	struct sbmac_softc *sbdma_eth;	        /* back pointer to associated MAC */
 	int              sbdma_channel;	/* channel number */
 	int		 sbdma_txdir;       /* direction (1=transmit) */
@@ -186,16 +186,16 @@ typedef struct sbmacdma_s {
 	volatile void __iomem *sbdma_dscrbase;	/* Descriptor base address */
 	volatile void __iomem *sbdma_dscrcnt;     /* Descriptor count register */
 	volatile void __iomem *sbdma_curdscr;	/* current descriptor address */
-	
+
 	/*
 	 * This stuff is for maintenance of the ring
 	 */
-	
+
 	sbdmadscr_t     *sbdma_dscrtable;	/* base of descriptor table */
 	sbdmadscr_t     *sbdma_dscrtable_end; /* end of descriptor table */
-	
+
 	struct sk_buff **sbdma_ctxtable;    /* context table, one per descr */
-	
+
 	paddr_t          sbdma_dscrtable_phys; /* and also the phys addr */
 	sbdmadscr_t     *sbdma_addptr;	/* next dscr for sw to add */
 	sbdmadscr_t     *sbdma_remptr;	/* next dscr for sw to remove */
@@ -207,15 +207,15 @@ typedef struct sbmacdma_s {
  ********************************************************************* */
 
 struct sbmac_softc {
-	
+
 	/*
 	 * Linux-specific things
 	 */
-	
+
 	struct net_device *sbm_dev;		/* pointer to linux device */
 	spinlock_t sbm_lock;		/* spin lock */
 	struct timer_list sbm_timer;     	/* for monitoring MII */
-	struct net_device_stats sbm_stats; 
+	struct net_device_stats sbm_stats;
 	int sbm_devflags;			/* current device flags */
 
 	int	     sbm_phy_oldbmsr;
@@ -223,16 +223,16 @@ struct sbmac_softc {
 	int	     sbm_phy_oldk1stsr;
 	int	     sbm_phy_oldlinkstat;
 	int sbm_buffersize;
-	
+
 	unsigned char sbm_phys[2];
-	
+
 	/*
 	 * Controller-specific things
 	 */
-	
+
 	volatile void __iomem *sbm_base;          /* MAC's base address */
 	sbmac_state_t    sbm_state;         /* current state */
-	
+
 	volatile void __iomem	*sbm_macenable;	/* MAC Enable Register */
 	volatile void __iomem	*sbm_maccfg;	/* MAC Configuration Register */
 	volatile void __iomem	*sbm_fifocfg;	/* FIFO configuration register */
@@ -241,13 +241,13 @@ struct sbmac_softc {
 	volatile void __iomem	*sbm_isr;	/* Interrupt status register */
 	volatile void __iomem	*sbm_imr;	/* Interrupt mask register */
 	volatile void __iomem	*sbm_mdio;	/* MDIO register */
-	
+
 	sbmac_speed_t    sbm_speed;		/* current speed */
 	sbmac_duplex_t   sbm_duplex;	/* current duplex */
 	sbmac_fc_t       sbm_fc;		/* current flow control setting */
-	
+
 	unsigned char    sbm_hwaddr[ETHER_ADDR_LEN];
-	
+
 	sbmacdma_t       sbm_txdma;		/* for now, only use channel 0 */
 	sbmacdma_t       sbm_rxdma;
 	int              rx_hw_checksum;
@@ -444,13 +444,13 @@ static uint64_t sbmac_orig_hwaddr[MAX_UN
 
 /**********************************************************************
  *  SBMAC_MII_SYNC(s)
- *  
+ *
  *  Synchronize with the MII - send a pattern of bits to the MII
  *  that will guarantee that it is ready to accept a command.
- *  
- *  Input parameters: 
+ *
+ *  Input parameters:
  *  	   s - sbmac structure
- *  	   
+ *
  *  Return value:
  *  	   nothing
  ********************************************************************* */
@@ -462,11 +462,11 @@ static void sbmac_mii_sync(struct sbmac_
 	int mac_mdio_genc;
 
 	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
-	
+
 	bits = M_MAC_MDIO_DIR_OUTPUT | M_MAC_MDIO_OUT;
-	
+
 	__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
-	
+
 	for (cnt = 0; cnt < 32; cnt++) {
 		__raw_writeq(bits | M_MAC_MDC | mac_mdio_genc, s->sbm_mdio);
 		__raw_writeq(bits | mac_mdio_genc, s->sbm_mdio);
@@ -475,11 +475,11 @@ static void sbmac_mii_sync(struct sbmac_
 
 /**********************************************************************
  *  SBMAC_MII_SENDDATA(s,data,bitcnt)
- *  
+ *
  *  Send some bits to the MII.  The bits to be sent are right-
  *  justified in the 'data' parameter.
- *  
- *  Input parameters: 
+ *
+ *  Input parameters:
  *  	   s - sbmac structure
  *  	   data - data to send
  *  	   bitcnt - number of bits to send
@@ -493,12 +493,12 @@ static void sbmac_mii_senddata(struct sb
 	int mac_mdio_genc;
 
 	mac_mdio_genc = __raw_readq(s->sbm_mdio) & M_MAC_GENC;
-	
+
 	bits = M_MAC_MDIO_DIR_OUTPUT;
[...2093 lines suppressed...]
 	 * Turn on the channel
 	 */
 
 	sbmac_set_channel_state(sc,sbmac_state_on);
-	
+
 	/*
 	 * XXX Station address is in dev->dev_addr
 	 */
-	
+
 	if (dev->if_port == 0)
-		dev->if_port = 0; 
-	
+		dev->if_port = 0;
+
 	netif_start_queue(dev);
-	
+
 	sbmac_set_rx_mode(dev);
-	
+
 	/* Set the timer to check for link beat. */
 	init_timer(&sc->sbm_timer);
 	sc->sbm_timer.expires = jiffies + 2 * HZ/100;
 	sc->sbm_timer.data = (unsigned long)dev;
 	sc->sbm_timer.function = &sbmac_timer;
 	add_timer(&sc->sbm_timer);
-	
+
 	return 0;
 }
 
@@ -2578,20 +2578,20 @@ static void sbmac_timer(unsigned long da
 	int mii_status;
 
 	spin_lock_irq (&sc->sbm_lock);
-	
+
 	/* make IFF_RUNNING follow the MII status bit "Link established" */
 	mii_status = sbmac_mii_read(sc, sc->sbm_phys[0], MII_BMSR);
-	
+
 	if ( (mii_status & BMSR_LINKSTAT) != (sc->sbm_phy_oldlinkstat) ) {
     	        sc->sbm_phy_oldlinkstat = mii_status & BMSR_LINKSTAT;
 		if (mii_status & BMSR_LINKSTAT) {
 			netif_carrier_on(dev);
 		}
 		else {
-			netif_carrier_off(dev);	
+			netif_carrier_off(dev);
 		}
 	}
-	
+
 	/*
 	 * Poll the PHY to see what speed we should be running at
 	 */
@@ -2609,9 +2609,9 @@ static void sbmac_timer(unsigned long da
 			sbmac_channel_start(sc);
 		}
 	}
-	
+
 	spin_unlock_irq (&sc->sbm_lock);
-	
+
 	sc->sbm_timer.expires = jiffies + next_tick;
 	add_timer(&sc->sbm_timer);
 }
@@ -2620,13 +2620,13 @@ static void sbmac_timer(unsigned long da
 static void sbmac_tx_timeout (struct net_device *dev)
 {
 	struct sbmac_softc *sc = netdev_priv(dev);
-	
+
 	spin_lock_irq (&sc->sbm_lock);
-	
-	
+
+
 	dev->trans_start = jiffies;
 	sc->sbm_stats.tx_errors++;
-	
+
 	spin_unlock_irq (&sc->sbm_lock);
 
 	printk (KERN_WARNING "%s: Transmit timed out\n",dev->name);
@@ -2639,13 +2639,13 @@ static struct net_device_stats *sbmac_ge
 {
 	struct sbmac_softc *sc = netdev_priv(dev);
 	unsigned long flags;
-	
+
 	spin_lock_irqsave(&sc->sbm_lock, flags);
-	
+
 	/* XXX update other stats here */
-	
+
 	spin_unlock_irqrestore(&sc->sbm_lock, flags);
-	
+
 	return &sc->sbm_stats;
 }
 
@@ -2662,8 +2662,8 @@ static void sbmac_set_rx_mode(struct net
 		/*
 		 * Promiscuous changed.
 		 */
-		
-		if (dev->flags & IFF_PROMISC) {	
+
+		if (dev->flags & IFF_PROMISC) {
 			/* Unconditionally log net taps. */
 			msg_flag = 1;
 			sbmac_promiscuous_mode(sc,1);
@@ -2674,18 +2674,18 @@ static void sbmac_set_rx_mode(struct net
 		}
 	}
 	spin_unlock_irqrestore(&sc->sbm_lock, flags);
-	
+
 	if (msg_flag) {
 		printk(KERN_NOTICE "%s: Promiscuous mode %sabled.\n",
 		       dev->name,(msg_flag==1)?"en":"dis");
 	}
-	
+
 	/*
 	 * Program the multicasts.  Do this every time.
 	 */
-	
+
 	sbmac_setmulti(sc);
-	
+
 }
 
 static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
@@ -2694,10 +2694,10 @@ static int sbmac_mii_ioctl(struct net_de
 	u16 *data = (u16 *)&rq->ifr_ifru;
 	unsigned long flags;
 	int retval;
-	
+
 	spin_lock_irqsave(&sc->sbm_lock, flags);
 	retval = 0;
-	
+
 	switch(cmd) {
 	case SIOCDEVPRIVATE:		/* Get the address of the PHY in use. */
 		data[0] = sc->sbm_phys[0] & 0x1f;
@@ -2719,7 +2719,7 @@ static int sbmac_mii_ioctl(struct net_de
 	default:
 		retval = -EOPNOTSUPP;
 	}
-	
+
 	spin_unlock_irqrestore(&sc->sbm_lock, flags);
 	return retval;
 }
@@ -2750,7 +2750,7 @@ static int sbmac_close(struct net_device
 
 	sbdma_emptyring(&(sc->sbm_txdma));
 	sbdma_emptyring(&(sc->sbm_rxdma));
-	
+
 	return 0;
 }
 
@@ -2781,7 +2781,7 @@ sbmac_init_module(void)
 	struct net_device *dev;
 	unsigned long port;
 	int chip_max_units;
-	
+
 	/*
 	 * For bringup when not using the firmware, we can pre-fill
 	 * the MAC addresses using the environment variables
@@ -2827,7 +2827,7 @@ sbmac_init_module(void)
 
 	        port = A_MAC_CHANNEL_BASE(idx);
 
-		/*	
+		/*
 		 * The R_MAC_ETHERNET_ADDR register will be set to some nonzero
 		 * value for us by the firmware if we're going to use this MAC.
 		 * If we find a zero, skip this MAC.
@@ -2845,7 +2845,7 @@ sbmac_init_module(void)
 		 */
 
 		dev = alloc_etherdev(sizeof(struct sbmac_softc));
-		if (!dev) 
+		if (!dev)
 			return -ENOMEM;	/* return ENOMEM */
 
 		printk(KERN_DEBUG "sbmac: configuring MAC at %lx\n", port);
---
0.99.8.GIT


--- NEW FILE 0633-sundance-include-MII-address-0-in-PHY-probe.txt ---
Subject: [PATCH] sundance: include MII address 0 in PHY probe
From: John W. Linville <linville at tuxdriver.com>
Date: 1129723654 -0400

Include MII address 0 at the end of the PHY scan.  This covers the
entire range of possible MII addresses.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sundance.c |    9 +++++----
 1 files changed, 5 insertions(+), 4 deletions(-)

applies-to: 2491ea6e4213531fc05a2beb612e175dd3e10dda
b06c093ed2dc968b3c140dafa55fa6c7b72169e5
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index d8a7e08..5de0554 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -609,16 +609,17 @@ static int __devinit sundance_probe1 (st
 
 	np->phys[0] = 1;		/* Default setting */
 	np->mii_preamble_required++;
-	for (phy = 1; phy < 32 && phy_idx < MII_CNT; phy++) {
+	for (phy = 1; phy <= 32 && phy_idx < MII_CNT; phy++) {
 		int mii_status = mdio_read(dev, phy, MII_BMSR);
+		int phyx = phy & 0x1f;
 		if (mii_status != 0xffff  &&  mii_status != 0x0000) {
-			np->phys[phy_idx++] = phy;
-			np->mii_if.advertising = mdio_read(dev, phy, MII_ADVERTISE);
+			np->phys[phy_idx++] = phyx;
+			np->mii_if.advertising = mdio_read(dev, phyx, MII_ADVERTISE);
 			if ((mii_status & 0x0040) == 0)
 				np->mii_preamble_required++;
 			printk(KERN_INFO "%s: MII PHY found at address %d, status "
 				   "0x%4.4x advertising %4.4x.\n",
-				   dev->name, phy, mii_status, np->mii_if.advertising);
+				   dev->name, phyx, mii_status, np->mii_if.advertising);
 		}
 	}
 	np->mii_preamble_required--;
---
0.99.8.GIT


--- NEW FILE 0634-e1000-Driver-version-white-space-comments-device-id-other.txt ---
Subject: [PATCH] e1000: Driver version, white space, comments, device id & other
From: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Date: 1129732808 -0400

Driver version, white space, comments, device id & other

Originally posted on 8/31 (and perhaps before)...I think it has not
been committed because the patch from that posting was damaged.  I'm
reposting to make sure it gets in... :-)

Signed-off-by: Mallikarjuna R Chilakala <mallikarjuna.chilakala at intel.com>
Signed-off-by: Ganesh Venkatesan <ganesh.venkatesan at intel.com>
Signed-off-by: John Ronciak <john.ronciak at intel.com>

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_main.c |   13 +++++++++----
 1 files changed, 9 insertions(+), 4 deletions(-)

applies-to: 1452c7664692586d65d0a8bfc17cd3b75936d0eb
07b8fede6da76ae6a0f547716c44b801a116bb4a
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 40128b9..6b72f6a 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -43,7 +43,7 @@ char e1000_driver_string[] = "Intel(R) P
 #else
 #define DRIVERNAPI "-NAPI"
 #endif
-#define DRV_VERSION		"6.0.60-k2"DRIVERNAPI
+#define DRV_VERSION "6.1.16-k2"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
 char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
 
@@ -80,6 +80,9 @@ static struct pci_device_id e1000_pci_tb
 	INTEL_E1000_ETHERNET_DEVICE(0x1026),
 	INTEL_E1000_ETHERNET_DEVICE(0x1027),
 	INTEL_E1000_ETHERNET_DEVICE(0x1028),
+	INTEL_E1000_ETHERNET_DEVICE(0x105E),
+	INTEL_E1000_ETHERNET_DEVICE(0x105F),
+	INTEL_E1000_ETHERNET_DEVICE(0x1060),
 	INTEL_E1000_ETHERNET_DEVICE(0x1075),
 	INTEL_E1000_ETHERNET_DEVICE(0x1076),
 	INTEL_E1000_ETHERNET_DEVICE(0x1077),
@@ -88,10 +91,13 @@ static struct pci_device_id e1000_pci_tb
 	INTEL_E1000_ETHERNET_DEVICE(0x107A),
 	INTEL_E1000_ETHERNET_DEVICE(0x107B),
 	INTEL_E1000_ETHERNET_DEVICE(0x107C),
+	INTEL_E1000_ETHERNET_DEVICE(0x107D),
+	INTEL_E1000_ETHERNET_DEVICE(0x107E),
+	INTEL_E1000_ETHERNET_DEVICE(0x107F),
 	INTEL_E1000_ETHERNET_DEVICE(0x108A),
 	INTEL_E1000_ETHERNET_DEVICE(0x108B),
 	INTEL_E1000_ETHERNET_DEVICE(0x108C),
-	INTEL_E1000_ETHERNET_DEVICE(0x1099),
+	INTEL_E1000_ETHERNET_DEVICE(0x109A),
 	/* required last entry */
 	{0,}
 };
@@ -398,8 +404,7 @@ e1000_down(struct e1000_adapter *adapter
 	e1000_clean_all_tx_rings(adapter);
 	e1000_clean_all_rx_rings(adapter);
 
-	/* If WoL is not enabled
-	 * and management mode is not IAMT
+	/* If WoL is not enabled and management mode is not IAMT
 	 * Power down the PHY so no link is implied when interface is down */
 	if(!adapter->wol && adapter->hw.mac_type >= e1000_82540 &&
 	   adapter->hw.media_type == e1000_media_type_copper &&
---
0.99.8.GIT


--- NEW FILE 0640-sb1250-mac-PHY-probing-fixes.txt ---
Subject: [PATCH] sb1250-mac: PHY probing fixes.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1129806088 +0100

Improve sb1250-mac driver to probe for PHYs at addresses other
than 1, such as the PHYs on BigSur.

Signed-Off-By: Andy Isaacson <adi at broadcom.com>
Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sb1250-mac.c |   36 ++++++++++++++++++++++++++++++++++++
 1 files changed, 36 insertions(+), 0 deletions(-)

applies-to: faddc60f0b27ed6d2a26f20c2c09f365dc4a2d7d
59b81827071a8ae7f399da533d268e1e33bfeeb7
diff --git a/drivers/net/sb1250-mac.c b/drivers/net/sb1250-mac.c
index d4c8ecd..aa4ca18 100644
--- a/drivers/net/sb1250-mac.c
+++ b/drivers/net/sb1250-mac.c
@@ -296,6 +296,7 @@ static void sbmac_set_rx_mode(struct net
 static int sbmac_mii_ioctl(struct net_device *dev, struct ifreq *rq, int cmd);
 static int sbmac_close(struct net_device *dev);
 static int sbmac_mii_poll(struct sbmac_softc *s,int noisy);
+static int sbmac_mii_probe(struct net_device *dev);
 
 static void sbmac_mii_sync(struct sbmac_softc *s);
 static void sbmac_mii_senddata(struct sbmac_softc *s,unsigned int data, int bitcnt);
@@ -433,6 +434,9 @@ static uint64_t sbmac_orig_hwaddr[MAX_UN
 
 #define	MII_BMCR	0x00 	/* Basic mode control register (rw) */
 #define	MII_BMSR	0x01	/* Basic mode status register (ro) */
+#define	MII_PHYIDR1	0x02
+#define	MII_PHYIDR2	0x03
+
 #define MII_K1STSR	0x0A	/* 1K Status Register (ro) */
 #define	MII_ANLPAR	0x05	/* Autonegotiation lnk partner abilities (rw) */
 
@@ -2432,6 +2436,15 @@ static int sbmac_open(struct net_device 
 		return -EBUSY;
 
 	/*
+	 * Probe phy address
+	 */
+
+	if(sbmac_mii_probe(dev) == -1) {
+		printk("%s: failed to probe PHY.\n", dev->name);
+		return -EINVAL;
+	}
+
+	/*
 	 * Configure default speed
 	 */
 
@@ -2464,6 +2477,29 @@ static int sbmac_open(struct net_device 
 	return 0;
 }
 
+static int sbmac_mii_probe(struct net_device *dev)
+{
+	int i;
+	struct sbmac_softc *s = netdev_priv(dev);
+	u16 bmsr, id1, id2;
+	u32 vendor, device;
+
+	for (i=1; i<31; i++) {
+	bmsr = sbmac_mii_read(s, i, MII_BMSR);
+		if (bmsr != 0) {
+			s->sbm_phys[0] = i;
+			id1 = sbmac_mii_read(s, i, MII_PHYIDR1);
+			id2 = sbmac_mii_read(s, i, MII_PHYIDR2);
+			vendor = ((u32)id1 << 6) | ((id2 >> 10) & 0x3f);
+			device = (id2 >> 4) & 0x3f;
+
+			printk(KERN_INFO "%s: found phy %d, vendor %06x part %02x\n",
+				dev->name, i, vendor, device);
+			return i;
+		}
+	}
+	return -1;
+}
 
 
 static int sbmac_mii_poll(struct sbmac_softc *s,int noisy)
---
0.99.8.GIT


--- NEW FILE 0663-PARISC-Change-the-driver-names-so-sys-bus-parisc-drivers-looks-better.txt ---
Subject: [PATCH] [PARISC] Change the driver names so /sys/bus/parisc/drivers/ looks better
From: Matthew Wilcox <willy at parisc-linux.org>
Date: 1129948583 -0400

Make /sys/bus/parisc/drivers look better by cleaning up parisc_driver
names.

Signed-off-by: Matthew Wilcox <willy at parisc-linux.org>

Signed-off-by: Kyle McMartin <kyle at parisc-linux.org>

---

 drivers/input/keyboard/hilkbd.c |    2 +-
 drivers/input/serio/gscps2.c    |    2 +-
 drivers/input/serio/hp_sdc.c    |    2 +-
 drivers/net/lasi_82596.c        |    2 +-
 drivers/parisc/asp.c            |    2 +-
 drivers/parisc/ccio-dma.c       |    2 +-
 drivers/parisc/dino.c           |    4 ++--
 drivers/parisc/eisa.c           |    2 +-
 drivers/parisc/hppb.c           |    2 +-
 drivers/parisc/lasi.c           |    2 +-
 drivers/scsi/lasi700.c          |    2 +-
 drivers/serial/mux.c            |    2 +-
 12 files changed, 13 insertions(+), 13 deletions(-)

applies-to: 61ae77a2c8faf7bb420be00d989b89c5ffd1f4ee
bdad1f836ab1ca2b18a625222f63f630cfd14e41
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index eecb77d..8aa81c9 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -299,7 +299,7 @@ static struct parisc_device_id hil_tbl[]
 MODULE_DEVICE_TABLE(parisc, hil_tbl);
 
 static struct parisc_driver hil_driver = {
-	.name =		"HIL",
+	.name =		"hil",
 	.id_table =	hil_tbl,
 	.probe =	hil_init_chip,
 };
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 897e4c1..4bad281 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -444,7 +444,7 @@ static struct parisc_device_id gscps2_de
 };
 
 static struct parisc_driver parisc_ps2_driver = {
-	.name		= "GSC PS2",
+	.name		= "gsc_ps2",
 	.id_table	= gscps2_device_tbl,
 	.probe		= gscps2_probe,
 	.remove		= gscps2_remove,
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index 7629452..045b9a7 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -764,7 +764,7 @@ MODULE_DEVICE_TABLE(parisc, hp_sdc_tbl);
 static int __init hp_sdc_init_hppa(struct parisc_device *d);
 
 static struct parisc_driver hp_sdc_driver = {
-	.name =		"HP SDC",
+	.name =		"hp_sdc",
 	.id_table =	hp_sdc_tbl,
 	.probe =	hp_sdc_init_hppa,
 };
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index 41bad07..180e526 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -1566,7 +1566,7 @@ static struct parisc_device_id lan_tbl[]
 MODULE_DEVICE_TABLE(parisc, lan_tbl);
 
 static struct parisc_driver lan_driver = {
-	.name		= "Apricot",
+	.name		= "lasi_82596",
 	.id_table	= lan_tbl,
 	.probe		= lan_init_chip,
 };
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 3886099..52f37b4 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -126,7 +126,7 @@ static struct parisc_device_id asp_tbl[]
 };
 
 struct parisc_driver asp_driver = {
-	.name =		"Asp",
+	.name =		"asp",
 	.id_table =	asp_tbl,
 	.probe =	asp_init_chip,
 };
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 0e98a9d..2bb1889 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1251,7 +1251,7 @@ static struct parisc_device_id ccio_tbl[
 static int ccio_probe(struct parisc_device *dev);
 
 static struct parisc_driver ccio_driver = {
-	.name =		"U2:Uturn",
+	.name =		"ccio",
 	.id_table =	ccio_tbl,
 	.probe =	ccio_probe,
 };
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 2f2dbef..8c61705 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -1027,9 +1027,9 @@ static struct parisc_device_id dino_tbl[
 };
 
 static struct parisc_driver dino_driver = {
-	.name =		"Dino",
+	.name =		"dino",
 	.id_table =	dino_tbl,
-	.probe =	dino_driver_callback,
+	.probe =	dino_probe,
 };
 
 /*
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 043d47a..0afeedd 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -397,7 +397,7 @@ static struct parisc_device_id eisa_tbl[
 MODULE_DEVICE_TABLE(parisc, eisa_tbl);
 
 static struct parisc_driver eisa_driver = {
-	.name =		"EISA Bus Adapter",
+	.name =		"eisa_ba",
 	.id_table =	eisa_tbl,
 	.probe =	eisa_probe,
 };
diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c
index e869c60..a6eae3e 100644
--- a/drivers/parisc/hppb.c
+++ b/drivers/parisc/hppb.c
@@ -93,7 +93,7 @@ static struct parisc_device_id hppb_tbl[
 };
 
 static struct parisc_driver hppb_driver = {
-        .name =         "Gecko Boa",
+        .name =         "gecko_boa",
         .id_table =     hppb_tbl,
 	.probe =        hppb_probe,
 };
diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
index cb84a4e..c776c37 100644
--- a/drivers/parisc/lasi.c
+++ b/drivers/parisc/lasi.c
@@ -233,7 +233,7 @@ static struct parisc_device_id lasi_tbl[
 };
 
 struct parisc_driver lasi_driver = {
-	.name =		"Lasi",
+	.name =		"lasi",
 	.id_table =	lasi_tbl,
 	.probe =	lasi_init_chip,
 };
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index 4cbb618..123f493 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -168,7 +168,7 @@ lasi700_driver_remove(struct parisc_devi
 }
 
 static struct parisc_driver lasi700_driver = {
-	.name =		"Lasi SCSI",
+	.name =		"lasi_scsi",
 	.id_table =	lasi700_ids,
 	.probe =	lasi700_probe,
 	.remove =	__devexit_p(lasi700_driver_remove),
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index 1890646..a12005b 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -497,7 +497,7 @@ static struct parisc_device_id mux_tbl[]
 MODULE_DEVICE_TABLE(parisc, mux_tbl);
 
 static struct parisc_driver serial_mux_driver = {
-	.name =		"Serial MUX",
+	.name =		"serial_mux",
 	.id_table =	mux_tbl,
 	.probe =	mux_probe,
 };
---
0.99.8.GIT


--- NEW FILE 0664-PARISC-Convert-parisc_device-to-use-struct-resource-for-hpa.txt ---
Subject: [PATCH] [PARISC] Convert parisc_device to use struct resource for hpa
From: Matthew Wilcox <willy at parisc-linux.org>
Date: 1129948600 -0400

Convert pa_dev->hpa from an unsigned long to a struct resource.

Signed-off-by: Matthew Wilcox <willy at parisc-linux.org>

Fix up users of ->hpa to use ->hpa.start instead.

Signed-off-by: Matthew Wilcox <willy at parisc-linux.org>

Signed-off-by: Kyle McMartin <kyle at parisc-linux.org>

---

 arch/parisc/kernel/perf.c          |   12 +++++++-----
 arch/parisc/kernel/processor.c     |    8 ++++----
 drivers/input/keyboard/hilkbd.c    |    4 ++--
 drivers/input/serio/gscps2.c       |    2 +-
 drivers/input/serio/hp_sdc.c       |    6 +++---
 drivers/net/lasi_82596.c           |    7 ++++---
 drivers/parisc/asp.c               |    4 ++--
 drivers/parisc/ccio-dma.c          |    4 ++--
 drivers/parisc/ccio-rm-dma.c       |    2 +-
 drivers/parisc/dino.c              |    6 +++---
 drivers/parisc/eisa.c              |    2 +-
 drivers/parisc/hppb.c              |    8 ++++----
 drivers/parisc/lasi.c              |    2 +-
 drivers/parisc/lba_pci.c           |   14 +++++++-------
 drivers/parisc/sba_iommu.c         |    6 +++---
 drivers/parisc/wax.c               |    2 +-
 drivers/parport/parport_gsc.c      |    5 +++--
 drivers/scsi/lasi700.c             |    2 +-
 drivers/scsi/zalon.c               |    4 ++--
 drivers/serial/8250_gsc.c          |    5 +++--
 drivers/serial/mux.c               |    2 +-
 include/asm-parisc/parisc-device.h |    2 +-
 sound/parisc/harmony.c             |    6 +++---
 23 files changed, 60 insertions(+), 55 deletions(-)

applies-to: b52b796d4f93b56b8cf23b23219c7083e363c96b
53f01bba49938f115237fe43a261c31ac13ae5c6
diff --git a/arch/parisc/kernel/perf.c b/arch/parisc/kernel/perf.c
index b3ad0a5..44670d6 100644
--- a/arch/parisc/kernel/perf.c
+++ b/arch/parisc/kernel/perf.c
@@ -746,7 +746,8 @@ static int perf_write_image(uint64_t *me
 	uint64_t *bptr;
 	uint32_t dwords;
 	uint32_t *intrigue_rdr;
-	uint64_t *intrigue_bitmask, tmp64, proc_hpa;
+	uint64_t *intrigue_bitmask, tmp64;
+	void __iomem *runway;
 	struct rdr_tbl_ent *tentry;
 	int i;
 
@@ -798,15 +799,16 @@ static int perf_write_image(uint64_t *me
 		return -1;
 	}
 
-	proc_hpa = cpu_device->hpa;
+	runway = ioremap(cpu_device->hpa.start, 4096);
 
 	/* Merge intrigue bits into Runway STATUS 0 */
-	tmp64 = __raw_readq(proc_hpa + RUNWAY_STATUS) & 0xffecfffffffffffful;
-	__raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), proc_hpa + RUNWAY_STATUS);
+	tmp64 = __raw_readq(runway + RUNWAY_STATUS) & 0xffecfffffffffffful;
+	__raw_writeq(tmp64 | (*memaddr++ & 0x0013000000000000ul), 
+		     runway + RUNWAY_STATUS);
 	
 	/* Write RUNWAY DEBUG registers */
 	for (i = 0; i < 8; i++) {
-		__raw_writeq(*memaddr++, proc_hpa + RUNWAY_DEBUG + i);
+		__raw_writeq(*memaddr++, runway + RUNWAY_DEBUG);
 	}
 
 	return 0; 
diff --git a/arch/parisc/kernel/processor.c b/arch/parisc/kernel/processor.c
index 13b721c..4f5bbcf 100644
--- a/arch/parisc/kernel/processor.c
+++ b/arch/parisc/kernel/processor.c
@@ -92,7 +92,7 @@ static int __init processor_probe(struct
 	 * May get overwritten by PAT code.
 	 */
 	cpuid = boot_cpu_data.cpu_count;
-	txn_addr = dev->hpa;	/* for legacy PDC */
+	txn_addr = dev->hpa.start;	/* for legacy PDC */
 
 #ifdef __LP64__
 	if (is_pdc_pat()) {
@@ -122,7 +122,7 @@ static int __init processor_probe(struct
  * boot time (ie shutdown a CPU from an OS perspective).
  */
 		/* get the cpu number */
-		status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa);
+		status = pdc_pat_cpu_get_number(&cpu_info, dev->hpa.start);
 
 		BUG_ON(PDC_OK != status);
 
@@ -130,7 +130,7 @@ static int __init processor_probe(struct
 			printk(KERN_WARNING "IGNORING CPU at 0x%x,"
 				" cpu_slot_id > NR_CPUS"
 				" (%ld > %d)\n",
-				dev->hpa, cpu_info.cpu_num, NR_CPUS);
+				dev->hpa.start, cpu_info.cpu_num, NR_CPUS);
 			/* Ignore CPU since it will only crash */
 			boot_cpu_data.cpu_count--;
 			return 1;
@@ -149,7 +149,7 @@ static int __init processor_probe(struct
 
 	p->loops_per_jiffy = loops_per_jiffy;
 	p->dev = dev;		/* Save IODC data in case we need it */
-	p->hpa = dev->hpa;	/* save CPU hpa */
+	p->hpa = dev->hpa.start;	/* save CPU hpa */
 	p->cpuid = cpuid;	/* save CPU id */
 	p->txn_addr = txn_addr;	/* save CPU IRQ address */
 #ifdef CONFIG_SMP
diff --git a/drivers/input/keyboard/hilkbd.c b/drivers/input/keyboard/hilkbd.c
index 8aa81c9..e7a1e14 100644
--- a/drivers/input/keyboard/hilkbd.c
+++ b/drivers/input/keyboard/hilkbd.c
@@ -278,11 +278,11 @@ static int __init
 hil_init_chip(struct parisc_device *dev)
 {
 	if (!dev->irq) {
-		printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa);
+		printk(KERN_WARNING "HIL: IRQ not found for HIL bus at 0x%08lx\n", dev->hpa.start);
 		return -ENODEV;
 	}
 
-	hil_base = dev->hpa;
+	hil_base = dev->hpa.start;
 	hil_irq  = dev->irq;
 	hil_dev.dev_id = dev;
 	
diff --git a/drivers/input/serio/gscps2.c b/drivers/input/serio/gscps2.c
index 4bad281..9790d71 100644
--- a/drivers/input/serio/gscps2.c
+++ b/drivers/input/serio/gscps2.c
@@ -331,7 +331,7 @@ static int __init gscps2_probe(struct pa
 {
 	struct gscps2port *ps2port;
 	struct serio *serio;
-	unsigned long hpa = dev->hpa;
+	unsigned long hpa = dev->hpa.start;
 	int ret;
 
 	if (!dev->irq)
diff --git a/drivers/input/serio/hp_sdc.c b/drivers/input/serio/hp_sdc.c
index 045b9a7..a10348b 100644
--- a/drivers/input/serio/hp_sdc.c
+++ b/drivers/input/serio/hp_sdc.c
@@ -875,9 +875,9 @@ static int __init hp_sdc_init_hppa(struc
 	hp_sdc.dev		= d;
 	hp_sdc.irq		= d->irq;
 	hp_sdc.nmi		= d->aux_irq;
-	hp_sdc.base_io		= d->hpa;
-	hp_sdc.data_io		= d->hpa + 0x800;
-	hp_sdc.status_io	= d->hpa + 0x801;
+	hp_sdc.base_io		= d->hpa.start;
+	hp_sdc.data_io		= d->hpa.start + 0x800;
+	hp_sdc.status_io	= d->hpa.start + 0x801;
 
 	return hp_sdc_init();
 }
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index 180e526..a63d8a3 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -1528,17 +1528,18 @@ lan_init_chip(struct parisc_device *dev)
 	
 	if (!dev->irq) {
 		printk(KERN_ERR "%s: IRQ not found for i82596 at 0x%lx\n",
-			__FILE__, dev->hpa);
+			__FILE__, dev->hpa.start);
 		return -ENODEV;
 	}
 
-	printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa, dev->irq);
+	printk(KERN_INFO "Found i82596 at 0x%lx, IRQ %d\n", dev->hpa.start,
+			dev->irq);
 
 	netdevice = alloc_etherdev(0);
 	if (!netdevice)
 		return -ENOMEM;
 
-	netdevice->base_addr = dev->hpa;
+	netdevice->base_addr = dev->hpa.start;
 	netdevice->irq = dev->irq;
 
 	retval = i82596_probe(netdevice, &dev->dev);
diff --git a/drivers/parisc/asp.c b/drivers/parisc/asp.c
index 52f37b4..558420b 100644
--- a/drivers/parisc/asp.c
+++ b/drivers/parisc/asp.c
@@ -77,12 +77,12 @@ asp_init_chip(struct parisc_device *dev)
 	struct gsc_irq gsc_irq;
 	int ret;
 
-	asp.version = gsc_readb(dev->hpa + ASP_VER_OFFSET) & 0xf;
+	asp.version = gsc_readb(dev->hpa.start + ASP_VER_OFFSET) & 0xf;
 	asp.name = (asp.version == 1) ? "Asp" : "Cutoff";
 	asp.hpa = ASP_INTERRUPT_ADDR;
 
 	printk(KERN_INFO "%s version %d at 0x%lx found.\n", 
-		asp.name, asp.version, dev->hpa);
+		asp.name, asp.version, dev->hpa.start);
 
 	/* the IRQ ASP should use */
 	ret = -EBUSY;
diff --git a/drivers/parisc/ccio-dma.c b/drivers/parisc/ccio-dma.c
index 2bb1889..80d0927 100644
--- a/drivers/parisc/ccio-dma.c
+++ b/drivers/parisc/ccio-dma.c
@@ -1546,7 +1546,7 @@ static int ccio_probe(struct parisc_devi
 
 	ioc->name = dev->id.hversion == U2_IOA_RUNWAY ? "U2" : "UTurn";
 
-	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa);
+	printk(KERN_INFO "Found %s at 0x%lx\n", ioc->name, dev->hpa.start);
 
 	for (i = 0; i < ioc_count; i++) {
 		ioc_p = &(*ioc_p)->next;
@@ -1554,7 +1554,7 @@ static int ccio_probe(struct parisc_devi
 	*ioc_p = ioc;
 
 	ioc->hw_path = dev->hw_path;
-	ioc->ioc_hpa = (struct ioa_registers *)dev->hpa;
+	ioc->ioc_regs = ioremap(dev->hpa.start, 4096);
 	ccio_ioc_init(ioc);
 	ccio_init_resources(ioc);
 	hppa_dma_ops = &ccio_ops;
diff --git a/drivers/parisc/ccio-rm-dma.c b/drivers/parisc/ccio-rm-dma.c
index 57e6385..356b835 100644
--- a/drivers/parisc/ccio-rm-dma.c
+++ b/drivers/parisc/ccio-rm-dma.c
@@ -167,7 +167,7 @@ ccio_probe(struct parisc_device *dev)
 {
 	printk(KERN_INFO "%s found %s at 0x%lx\n", MODULE_NAME,
 			dev->id.hversion == U2_BC_GSC ? "U2" : "UTurn",
-			dev->hpa);
+			dev->hpa.start);
 
 /*
 ** FIXME - should check U2 registers to verify it's really running
diff --git a/drivers/parisc/dino.c b/drivers/parisc/dino.c
index 8c61705..37820b0 100644
--- a/drivers/parisc/dino.c
+++ b/drivers/parisc/dino.c
@@ -902,15 +902,15 @@ void ccio_cujo20_fixup(struct parisc_dev
 ** If so, initialize the chip appropriately (card-mode vs bridge mode).
 ** Much of the initialization is common though.
 */
-static int __init
-dino_driver_callback(struct parisc_device *dev)
+static int __init dino_probe(struct parisc_device *dev)
 {
 	struct dino_device *dino_dev;	// Dino specific control struct
 	const char *version = "unknown";
 	char *name;
 	int is_cujo = 0;
 	struct pci_bus *bus;
-	
+	unsigned long hpa = dev->hpa.start;
+
 	name = "Dino";
 	if (is_card_dino(&dev->id)) {
 		version = "3.x (card mode)";
diff --git a/drivers/parisc/eisa.c b/drivers/parisc/eisa.c
index 0afeedd..6362bf9 100644
--- a/drivers/parisc/eisa.c
+++ b/drivers/parisc/eisa.c
@@ -315,7 +315,7 @@ static int __devinit eisa_probe(struct p
 	char *name = is_mongoose(dev) ? "Mongoose" : "Wax";
 
 	printk(KERN_INFO "%s EISA Adapter found at 0x%08lx\n", 
-		name, dev->hpa);
+		name, dev->hpa.start);
 
 	eisa_dev.hba.dev = dev;
 	eisa_dev.hba.iommu = ccio_get_iommu(dev);
diff --git a/drivers/parisc/hppb.c b/drivers/parisc/hppb.c
index a6eae3e..5edf93f 100644
--- a/drivers/parisc/hppb.c
+++ b/drivers/parisc/hppb.c
@@ -68,14 +68,14 @@ static int hppb_probe(struct parisc_devi
 		memset(card->next, '\0', sizeof(struct hppb_card));
 		card = card->next;
 	}
-        printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa);
+        printk(KERN_INFO "Found GeckoBoa at 0x%lx\n", dev->hpa.start);
 
-	card->hpa = dev->hpa;
+	card->hpa = dev->hpa.start;
 	card->mmio_region.name = "HP-PB Bus";
 	card->mmio_region.flags = IORESOURCE_MEM;
 
-	card->mmio_region.start = __raw_readl(dev->hpa + IO_IO_LOW);
-	card->mmio_region.end = __raw_readl(dev->hpa + IO_IO_HIGH) - 1;
+	card->mmio_region.start = gsc_readl(dev->hpa.start + IO_IO_LOW);
+	card->mmio_region.end = gsc_readl(dev->hpa.start + IO_IO_HIGH) - 1;
 
 	status = ccio_request_resource(dev, &card->mmio_region);
 	if(status < 0) {
diff --git a/drivers/parisc/lasi.c b/drivers/parisc/lasi.c
index c776c37..a8c2039 100644
--- a/drivers/parisc/lasi.c
+++ b/drivers/parisc/lasi.c
@@ -175,7 +175,7 @@ lasi_init_chip(struct parisc_device *dev
 		return -ENOMEM;
 
 	lasi->name = "Lasi";
-	lasi->hpa = dev->hpa;
+	lasi->hpa = dev->hpa.start;
 
 	/* Check the 4-bit (yes, only 4) version register */
 	lasi->version = gsc_readl(lasi->hpa + LASI_VER) & 0xf;
diff --git a/drivers/parisc/lba_pci.c b/drivers/parisc/lba_pci.c
index 7fdd80b..5e495dc 100644
--- a/drivers/parisc/lba_pci.c
+++ b/drivers/parisc/lba_pci.c
@@ -1288,7 +1288,7 @@ lba_legacy_resources(struct parisc_devic
 		** Adjust "window" for this rope.
 		*/
 		rsize /= ROPES_PER_IOC;
-		r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa);
+		r->start += (rsize + 1) * LBA_NUM(pa_dev->hpa.start);
 		r->end = r->start + rsize;
 	} else {
 		r->end = r->start = 0;	/* Not enabled. */
@@ -1458,7 +1458,7 @@ lba_driver_probe(struct parisc_device *d
 	u32 func_class;
 	void *tmp_obj;
 	char *version;
-	void __iomem *addr = ioremap(dev->hpa, 4096);
+	void __iomem *addr = ioremap(dev->hpa.start, 4096);
 
 	/* Read HW Rev First */
 	func_class = READ_REG32(addr + LBA_FCLASS);
@@ -1476,7 +1476,7 @@ lba_driver_probe(struct parisc_device *d
 		}
 
 		printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
-			MODULE_NAME, version, func_class & 0xf, dev->hpa);
+			MODULE_NAME, version, func_class & 0xf, dev->hpa.start);
 
 		if (func_class < 2) {
 			printk(KERN_WARNING "Can't support LBA older than "
@@ -1503,17 +1503,17 @@ lba_driver_probe(struct parisc_device *d
                  * but for the mask for func_class.
                  */ 
 		printk(KERN_INFO "%s version %s (0x%x) found at 0x%lx\n",
-			MODULE_NAME, version, func_class & 0xff, dev->hpa);
+		       MODULE_NAME, version, func_class & 0xff, dev->hpa.start);
 		cfg_ops = &mercury_cfg_ops;
 	} else {
-		printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa);
+		printk(KERN_ERR "Unknown LBA found at 0x%lx\n", dev->hpa.start);
 		return -ENODEV;
 	}
 
 	/*
 	** Tell I/O SAPIC driver we have a IRQ handler/region.
 	*/
-	tmp_obj = iosapic_register(dev->hpa + LBA_IOSAPIC_BASE);
+	tmp_obj = iosapic_register(dev->hpa.start + LBA_IOSAPIC_BASE);
 
 	/* NOTE: PCI devices (e.g. 103c:1005 graphics card) which don't
 	**	have an IRT entry will get NULL back from iosapic code.
@@ -1635,7 +1635,7 @@ void __init lba_init(void)
 */
 void lba_set_iregs(struct parisc_device *lba, u32 ibase, u32 imask)
 {
-	void __iomem * base_addr = ioremap(lba->hpa, 4096);
+	void __iomem * base_addr = ioremap(lba->hpa.start, 4096);
 
 	imask <<= 2;	/* adjust for hints - 2 more bits */
 
diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c
index a8405f0..6256ad3 100644
--- a/drivers/parisc/sba_iommu.c
+++ b/drivers/parisc/sba_iommu.c
@@ -1600,7 +1600,7 @@ sba_ioc_init(struct parisc_device *sba, 
 
 static void __iomem *ioc_remap(struct sba_device *sba_dev, int offset)
 {
-	return ioremap(sba_dev->dev->hpa + offset, SBA_FUNC_SIZE);
+	return ioremap(sba_dev->dev->hpa.start + offset, SBA_FUNC_SIZE);
 }
 
 static void sba_hw_init(struct sba_device *sba_dev)
@@ -1978,7 +1978,7 @@ sba_driver_callback(struct parisc_device
 	u32 func_class;
 	int i;
 	char *version;
-	void __iomem *sba_addr = ioremap(dev->hpa, SBA_FUNC_SIZE);
+	void __iomem *sba_addr = ioremap(dev->hpa.start, SBA_FUNC_SIZE);
 
 	sba_dump_ranges(sba_addr);
 
@@ -2020,7 +2020,7 @@ sba_driver_callback(struct parisc_device
 	}
 
 	printk(KERN_INFO "%s found %s at 0x%lx\n",
-		MODULE_NAME, version, dev->hpa);
+		MODULE_NAME, version, dev->hpa.start);
 
 	sba_dev = kmalloc(sizeof(struct sba_device), GFP_KERNEL);
 	if (!sba_dev) {
diff --git a/drivers/parisc/wax.c b/drivers/parisc/wax.c
index e547d7d..17dce2a 100644
--- a/drivers/parisc/wax.c
+++ b/drivers/parisc/wax.c
@@ -81,7 +81,7 @@ wax_init_chip(struct parisc_device *dev)
 		return -ENOMEM;
 
 	wax->name = "wax";
-	wax->hpa = dev->hpa;
+	wax->hpa = dev->hpa.start;
 
 	wax->version = 0;   /* gsc_readb(wax->hpa+WAX_VER); */
 	printk(KERN_INFO "%s at 0x%lx found.\n", wax->name, wax->hpa);
diff --git a/drivers/parport/parport_gsc.c b/drivers/parport/parport_gsc.c
index 02d72ac..fde29a7 100644
--- a/drivers/parport/parport_gsc.c
+++ b/drivers/parport/parport_gsc.c
@@ -359,11 +359,12 @@ static int __devinit parport_init_chip(s
 	unsigned long port;
 
 	if (!dev->irq) {
-		printk("IRQ not found for parallel device at 0x%lx\n", dev->hpa);
+		printk(KERN_WARNING "IRQ not found for parallel device at 0x%lx\n",
+			dev->hpa.start);
 		return -ENODEV;
 	}
 
-	port = dev->hpa + PARPORT_GSC_OFFSET;
+	port = dev->hpa.start + PARPORT_GSC_OFFSET;
 	
 	/* some older machines with ASP-chip don't support
 	 * the enhanced parport modes.
diff --git a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
index 123f493..8028418 100644
--- a/drivers/scsi/lasi700.c
+++ b/drivers/scsi/lasi700.c
@@ -98,7 +98,7 @@ MODULE_DEVICE_TABLE(parisc, lasi700_ids)
 static int __init
 lasi700_probe(struct parisc_device *dev)
 {
-	unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET;
+	unsigned long base = dev->hpa.start + LASI_SCSI_CORE_OFFSET;
 	struct NCR_700_Host_Parameters *hostdata;
 	struct Scsi_Host *host;
 
diff --git a/drivers/scsi/zalon.c b/drivers/scsi/zalon.c
index 5a51051..b131432 100644
--- a/drivers/scsi/zalon.c
+++ b/drivers/scsi/zalon.c
@@ -88,7 +88,7 @@ zalon_probe(struct parisc_device *dev)
 	struct gsc_irq gsc_irq;
 	u32 zalon_vers;
 	int error = -ENODEV;
-	void __iomem *zalon = ioremap(dev->hpa, 4096);
+	void __iomem *zalon = ioremap(dev->hpa.start, 4096);
 	void __iomem *io_port = zalon + GSC_SCSI_ZALON_OFFSET;
 	static int unit = 0;
 	struct Scsi_Host *host;
@@ -127,7 +127,7 @@ zalon_probe(struct parisc_device *dev)
 	device.chip		= zalon720_chip;
 	device.host_id		= 7;
 	device.dev		= &dev->dev;
-	device.slot.base	= dev->hpa + GSC_SCSI_ZALON_OFFSET;
+	device.slot.base	= dev->hpa.start + GSC_SCSI_ZALON_OFFSET;
 	device.slot.base_v	= io_port;
 	device.slot.irq		= dev->irq;
 	device.differential	= 2;
diff --git a/drivers/serial/8250_gsc.c b/drivers/serial/8250_gsc.c
index 431aa57..abc5a0c 100644
--- a/drivers/serial/8250_gsc.c
+++ b/drivers/serial/8250_gsc.c
@@ -42,12 +42,13 @@ serial_init_chip(struct parisc_device *d
 		 */
 		if (parisc_parent(dev)->id.hw_type != HPHW_IOA) {
 			printk(KERN_INFO "Serial: device 0x%lx not configured.\n"
-				"Enable support for Wax, Lasi, Asp or Dino.\n", dev->hpa);
+				"Enable support for Wax, Lasi, Asp or Dino.\n",
+				dev->hpa.start);
 		}
 		return -ENODEV;
 	}
 
-	address = dev->hpa;
+	address = dev->hpa.start;
 	if (dev->id.sversion != 0x8d) {
 		address += 0x800;
 	}
diff --git a/drivers/serial/mux.c b/drivers/serial/mux.c
index a12005b..009ce83 100644
--- a/drivers/serial/mux.c
+++ b/drivers/serial/mux.c
@@ -444,7 +444,7 @@ static int __init mux_probe(struct paris
 	unsigned long bytecnt;
 	struct uart_port *port;
 
-	status = pdc_iodc_read(&bytecnt, dev->hpa, 0, iodc_data, 32);
+	status = pdc_iodc_read(&bytecnt, dev->hpa.start, 0, iodc_data, 32);
 	if(status != PDC_OK) {
 		printk(KERN_ERR "Serial mux: Unable to read IODC.\n");
 		return 1;
diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h
index cbde8b4..1d247e3 100644
--- a/include/asm-parisc/parisc-device.h
+++ b/include/asm-parisc/parisc-device.h
@@ -1,7 +1,7 @@
 #include <linux/device.h>
 
 struct parisc_device {
-	unsigned long   hpa;		/* Hard Physical Address */
+	struct resource hpa;		/* Hard Physical Address */
 	struct parisc_device_id id;
 	struct parisc_driver *driver;	/* Driver for this device */
 	char		name[80];	/* The hardware description */
diff --git a/sound/parisc/harmony.c b/sound/parisc/harmony.c
index f560dd8..8b3ea26 100644
--- a/sound/parisc/harmony.c
+++ b/sound/parisc/harmony.c
@@ -852,14 +852,14 @@ snd_harmony_create(snd_card_t *card, 
 	memset(&h->pbuf, 0, sizeof(h->pbuf));
 	memset(&h->cbuf, 0, sizeof(h->cbuf));
 
-	h->hpa = padev->hpa;
+	h->hpa = padev->hpa.start;
 	h->card = card;
 	h->dev = padev;
 	h->irq = padev->irq;
-	h->iobase = ioremap_nocache(padev->hpa, HARMONY_SIZE);
+	h->iobase = ioremap_nocache(padev->hpa.start, HARMONY_SIZE);
 	if (h->iobase == NULL) {
 		printk(KERN_ERR PFX "unable to remap hpa 0x%lx\n",
-		       padev->hpa);
+		       padev->hpa.start);
 		err = -EBUSY;
 		goto free_and_ret;
 	}
---
0.99.8.GIT


--- NEW FILE 0702-PARISC-Add-NETPOLL-support-to-lasi_82596.txt ---
Subject: [PATCH] [PARISC] Add NETPOLL support to lasi_82596
From: Sven Schnelle <svens at gmx.de>
Date: 1129949715 -0400

add netpoll support
Patch by Sven Schnelle <svens at gmx.de>

Signed-off-by: Sven Schnelle <svens at gmx.de>
Signed-off-by: Helge Deller <deller at parisc-linux.org>

Signed-off-by: Kyle McMartin <kyle at parisc-linux.org>

---

 drivers/net/lasi_82596.c |   21 ++++++++++++++++++---
 1 files changed, 18 insertions(+), 3 deletions(-)

applies-to: 4da7851b8972bb7251789b3862642aca8274aa07
c2709020adb442f7d25f0805af08a3b6cfedd7be
diff --git a/drivers/net/lasi_82596.c b/drivers/net/lasi_82596.c
index a63d8a3..f7b7238 100644
--- a/drivers/net/lasi_82596.c
+++ b/drivers/net/lasi_82596.c
@@ -415,6 +415,10 @@ static int rx_ring_size = RX_RING_SIZE;
 static int ticks_limit = 100;
 static int max_cmd_backlog = TX_RING_SIZE-1;
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void i596_poll_controller(struct net_device *dev);
+#endif
+
 
 static inline void CA(struct net_device *dev)
 {
@@ -636,11 +640,11 @@ static int init_i596_mem(struct net_devi
 
 	disable_irq(dev->irq);	/* disable IRQs from LAN */
 	DEB(DEB_INIT,
-		printk("RESET 82596 port: %p (with IRQ %d disabled)\n",
-		       (void*)(dev->base_addr + PA_I82596_RESET),
+		printk("RESET 82596 port: %lx (with IRQ %d disabled)\n",
+		       (dev->base_addr + PA_I82596_RESET),
 		       dev->irq));
 	
-	gsc_writel(0, (void*)(dev->base_addr + PA_I82596_RESET)); /* Hard Reset */
+	gsc_writel(0, (dev->base_addr + PA_I82596_RESET)); /* Hard Reset */
 	udelay(100);			/* Wait 100us - seems to help */
 
 	/* change the scp address */
@@ -1209,6 +1213,9 @@ static int __devinit i82596_probe(struct
 	dev->set_multicast_list = set_multicast_list;
 	dev->tx_timeout = i596_tx_timeout;
 	dev->watchdog_timeo = TX_TIMEOUT;
+#ifdef CONFIG_NET_POLL_CONTROLLER
+	dev->poll_controller = i596_poll_controller;
+#endif
 
 	dev->priv = (void *)(dev->mem_start);
 
@@ -1242,6 +1249,14 @@ static int __devinit i82596_probe(struct
 	return 0;
 }
 
+#ifdef CONFIG_NET_POLL_CONTROLLER
+static void i596_poll_controller(struct net_device *dev)
+{
+	disable_irq(dev->irq);
+	i596_interrupt(dev->irq, dev, NULL);
+	enable_irq(dev->irq);
+}
+#endif
 
 static irqreturn_t i596_interrupt(int irq, void *dev_id, struct pt_regs *regs)
 {
---
0.99.8.GIT


--- NEW FILE 0773-netdrvr-forcedeth-scatter-gather-and-segmentation-offload-support.txt ---
Subject: [PATCH] [netdrvr forcedeth] scatter gather and segmentation offload support
From: Ayaz Abdulla <aabdulla at nvidia.com>
Date: 1130302284 -0400

also:
- eliminate use of pointless get_nvpriv() wrapper,
  and use netdev_priv() directly.
- use NETDEV_TX_xxx return codes

---

 drivers/net/forcedeth.c |  249 +++++++++++++++++++++++++++++++----------------
 1 files changed, 162 insertions(+), 87 deletions(-)

applies-to: 096e552a197400429a033f235fadd4ccbe886f01
ac9c18974f7d08cdedfb1e9599faa8c851c7cef9
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index e5f4802..22aec6e 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -96,6 +96,7 @@
  *      0.42: 06 Aug 2005: Fix lack of link speed initialization
  *			   in the second (and later) nv_open call
  *      0.43: 10 Aug 2005: Add support for tx checksum.
+ *      0.44: 20 Aug 2005: Add support for scatter gather and segmentation.
  *
  * Known bugs:
  * We suspect that on some hardware no TX done interrupts are generated.
@@ -107,7 +108,7 @@
  * DEV_NEED_TIMERIRQ will not harm you on sane hardware, only generating a few
  * superfluous timer interrupts from the nic.
  */
-#define FORCEDETH_VERSION		"0.43"
+#define FORCEDETH_VERSION		"0.44"
 #define DRV_NAME			"forcedeth"
 
 #include <linux/module.h>
@@ -340,6 +341,8 @@ typedef union _ring_type {
 /* error and valid are the same for both */
 #define NV_TX2_ERROR		(1<<30)
 #define NV_TX2_VALID		(1<<31)
+#define NV_TX2_TSO		(1<<28)
+#define NV_TX2_TSO_SHIFT	14
 #define NV_TX2_CHECKSUM_L3	(1<<27)
 #define NV_TX2_CHECKSUM_L4	(1<<26)
 
@@ -542,7 +545,7 @@ static inline struct fe_priv *get_nvpriv
 
 static inline u8 __iomem *get_hwbase(struct net_device *dev)
 {
-	return get_nvpriv(dev)->base;
+	return ((struct fe_priv *)netdev_priv(dev))->base;
 }
 
 static inline void pci_push(u8 __iomem *base)
@@ -631,7 +634,7 @@ static int mii_rw(struct net_device *dev
 
 static int phy_reset(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u32 miicontrol;
 	unsigned int tries = 0;
 
@@ -734,7 +737,7 @@ static int phy_init(struct net_device *d
 
 static void nv_start_rx(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 
 	dprintk(KERN_DEBUG "%s: nv_start_rx\n", dev->name);
@@ -790,7 +793,7 @@ static void nv_stop_tx(struct net_device
 
 static void nv_txrx_reset(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 
 	dprintk(KERN_DEBUG "%s: nv_txrx_reset\n", dev->name);
@@ -809,7 +812,7 @@ static void nv_txrx_reset(struct net_dev
  */
 static struct net_device_stats *nv_get_stats(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 
 	/* It seems that the nic always generates interrupts and doesn't
 	 * accumulate errors internally. Thus the current values in np->stats
@@ -825,7 +828,7 @@ static struct net_device_stats *nv_get_s
  */
 static int nv_alloc_rx(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	unsigned int refill_rx = np->refill_rx;
 	int nr;
 
@@ -869,7 +872,7 @@ static int nv_alloc_rx(struct net_device
 static void nv_do_rx_refill(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *) data;
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 
 	disable_irq(dev->irq);
 	if (nv_alloc_rx(dev)) {
@@ -883,7 +886,7 @@ static void nv_do_rx_refill(unsigned lon
 
 static void nv_init_rx(struct net_device *dev) 
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	int i;
 
 	np->cur_rx = RX_RING;
@@ -897,15 +900,17 @@ static void nv_init_rx(struct net_device
 
 static void nv_init_tx(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	int i;
 
 	np->next_tx = np->nic_tx = 0;
-	for (i = 0; i < TX_RING; i++)
+	for (i = 0; i < TX_RING; i++) {
 		if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
 			np->tx_ring.orig[i].FlagLen = 0;
 	        else
 			np->tx_ring.ex[i].FlagLen = 0;
+		np->tx_skbuff[i] = NULL;
+	}
 }
 
 static int nv_init_ring(struct net_device *dev)
@@ -915,21 +920,44 @@ static int nv_init_ring(struct net_devic
 	return nv_alloc_rx(dev);
 }
 
+static void nv_release_txskb(struct net_device *dev, unsigned int skbnr)
+{
+	struct fe_priv *np = netdev_priv(dev);
+	struct sk_buff *skb = np->tx_skbuff[skbnr];
+	unsigned int j, entry, fragments;
+			
+	dprintk(KERN_INFO "%s: nv_release_txskb for skbnr %d, skb %p\n",
+		dev->name, skbnr, np->tx_skbuff[skbnr]);
+	
+	entry = skbnr;
+	if ((fragments = skb_shinfo(skb)->nr_frags) != 0) {
+		for (j = fragments; j >= 1; j--) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[j-1];
+			pci_unmap_page(np->pci_dev, np->tx_dma[entry],
+				       frag->size,
+				       PCI_DMA_TODEVICE);
+			entry = (entry - 1) % TX_RING;
+		}
+	}
+	pci_unmap_single(np->pci_dev, np->tx_dma[entry],
+			 skb->len - skb->data_len,
+			 PCI_DMA_TODEVICE);
+	dev_kfree_skb_irq(skb);
+	np->tx_skbuff[skbnr] = NULL;
+}
+
 static void nv_drain_tx(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
-	int i;
+	struct fe_priv *np = netdev_priv(dev);
+	unsigned int i;
+	
 	for (i = 0; i < TX_RING; i++) {
 		if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
 			np->tx_ring.orig[i].FlagLen = 0;
 		else
 			np->tx_ring.ex[i].FlagLen = 0;
 		if (np->tx_skbuff[i]) {
-			pci_unmap_single(np->pci_dev, np->tx_dma[i],
-						np->tx_skbuff[i]->len,
-						PCI_DMA_TODEVICE);
-			dev_kfree_skb(np->tx_skbuff[i]);
-			np->tx_skbuff[i] = NULL;
+			nv_release_txskb(dev, i);
 			np->stats.tx_dropped++;
 		}
 	}
@@ -937,7 +965,7 @@ static void nv_drain_tx(struct net_devic
 
 static void nv_drain_rx(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	int i;
 	for (i = 0; i < RX_RING; i++) {
 		if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
@@ -967,29 +995,69 @@ static void drain_ring(struct net_device
  */
 static int nv_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
-	int nr = np->next_tx % TX_RING;
-	u32 tx_checksum = (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
+	struct fe_priv *np = netdev_priv(dev);
+	u32 tx_flags_extra = (np->desc_ver == DESC_VER_1 ? NV_TX_LASTPACKET : NV_TX2_LASTPACKET);
+	unsigned int fragments = skb_shinfo(skb)->nr_frags;
+	unsigned int nr = (np->next_tx + fragments) % TX_RING;
+	unsigned int i;
+
+	spin_lock_irq(&np->lock);
+
+	if ((np->next_tx - np->nic_tx + fragments) > TX_LIMIT_STOP) {
+		spin_unlock_irq(&np->lock);
+		netif_stop_queue(dev);
+		return NETDEV_TX_BUSY;
+	}
 
 	np->tx_skbuff[nr] = skb;
-	np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data,skb->len,
-					PCI_DMA_TODEVICE);
+	
+	if (fragments) {
+		dprintk(KERN_DEBUG "%s: nv_start_xmit: buffer contains %d fragments\n", dev->name, fragments);
+		/* setup descriptors in reverse order */
+		for (i = fragments; i >= 1; i--) {
+			skb_frag_t *frag = &skb_shinfo(skb)->frags[i-1];
+			np->tx_dma[nr] = pci_map_page(np->pci_dev, frag->page, frag->page_offset, frag->size,
+							PCI_DMA_TODEVICE);
 
-	if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
+			if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
+				np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
+				np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
+			} else {
+				np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
+				np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
+				np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (frag->size-1) | np->tx_flags | tx_flags_extra);
+			}
+			
+			nr = (nr - 1) % TX_RING;
+
+			if (np->desc_ver == DESC_VER_1)
+				tx_flags_extra &= ~NV_TX_LASTPACKET;
+			else
+				tx_flags_extra &= ~NV_TX2_LASTPACKET;		
+		}
+	}
+
+#ifdef NETIF_F_TSO
+	if (skb_shinfo(skb)->tso_size)
+		tx_flags_extra |= NV_TX2_TSO | (skb_shinfo(skb)->tso_size << NV_TX2_TSO_SHIFT);
+	else
+#endif
+	tx_flags_extra |= (skb->ip_summed == CHECKSUM_HW ? (NV_TX2_CHECKSUM_L3|NV_TX2_CHECKSUM_L4) : 0);
+
+	np->tx_dma[nr] = pci_map_single(np->pci_dev, skb->data, skb->len-skb->data_len,
+					PCI_DMA_TODEVICE);
+	
+	if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2) {
 		np->tx_ring.orig[nr].PacketBuffer = cpu_to_le32(np->tx_dma[nr]);
-	else {
+		np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
+	} else {
 		np->tx_ring.ex[nr].PacketBufferHigh = cpu_to_le64(np->tx_dma[nr]) >> 32;
 		np->tx_ring.ex[nr].PacketBufferLow = cpu_to_le64(np->tx_dma[nr]) & 0x0FFFFFFFF;
-	}
+		np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-skb->data_len-1) | np->tx_flags | tx_flags_extra);
+	}	
 
-	spin_lock_irq(&np->lock);
-	wmb();
-	if (np->desc_ver == DESC_VER_1 || np->desc_ver == DESC_VER_2)
-		np->tx_ring.orig[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags | tx_checksum);
-	else
-		np->tx_ring.ex[nr].FlagLen = cpu_to_le32( (skb->len-1) | np->tx_flags | tx_checksum);
-	dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission\n",
-				dev->name, np->next_tx);
+	dprintk(KERN_DEBUG "%s: nv_start_xmit: packet packet %d queued for transmission. tx_flags_extra: %x\n",
+				dev->name, np->next_tx, tx_flags_extra);
 	{
 		int j;
 		for (j=0; j<64; j++) {
@@ -1000,15 +1068,13 @@ static int nv_start_xmit(struct sk_buff 
 		dprintk("\n");
 	}
 
-	np->next_tx++;
+	np->next_tx += 1 + fragments;
 
 	dev->trans_start = jiffies;
-	if (np->next_tx - np->nic_tx >= TX_LIMIT_STOP)
-		netif_stop_queue(dev);
 	spin_unlock_irq(&np->lock);
 	writel(NVREG_TXRXCTL_KICK|np->txrxctl_bits, get_hwbase(dev) + NvRegTxRxControl);
 	pci_push(get_hwbase(dev));
-	return 0;
+	return NETDEV_TX_OK;
 }
 
 /*
@@ -1018,9 +1084,10 @@ static int nv_start_xmit(struct sk_buff 
  */
 static void nv_tx_done(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u32 Flags;
-	int i;
+	unsigned int i;
+	struct sk_buff *skb;
 
 	while (np->nic_tx != np->next_tx) {
 		i = np->nic_tx % TX_RING;
@@ -1035,35 +1102,38 @@ static void nv_tx_done(struct net_device
 		if (Flags & NV_TX_VALID)
 			break;
 		if (np->desc_ver == DESC_VER_1) {
-			if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
-							NV_TX_UNDERFLOW|NV_TX_ERROR)) {
-				if (Flags & NV_TX_UNDERFLOW)
-					np->stats.tx_fifo_errors++;
-				if (Flags & NV_TX_CARRIERLOST)
-					np->stats.tx_carrier_errors++;
-				np->stats.tx_errors++;
-			} else {
-				np->stats.tx_packets++;
-				np->stats.tx_bytes += np->tx_skbuff[i]->len;
+			if (Flags & NV_TX_LASTPACKET) {
+				skb = np->tx_skbuff[i];
+				if (Flags & (NV_TX_RETRYERROR|NV_TX_CARRIERLOST|NV_TX_LATECOLLISION|
+					     NV_TX_UNDERFLOW|NV_TX_ERROR)) {
+					if (Flags & NV_TX_UNDERFLOW)
+						np->stats.tx_fifo_errors++;
+					if (Flags & NV_TX_CARRIERLOST)
+						np->stats.tx_carrier_errors++;
+					np->stats.tx_errors++;
+				} else {
+					np->stats.tx_packets++;
+					np->stats.tx_bytes += skb->len;
+				}
+				nv_release_txskb(dev, i);
 			}
 		} else {
-			if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
-							NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
-				if (Flags & NV_TX2_UNDERFLOW)
-					np->stats.tx_fifo_errors++;
-				if (Flags & NV_TX2_CARRIERLOST)
-					np->stats.tx_carrier_errors++;
-				np->stats.tx_errors++;
-			} else {
-				np->stats.tx_packets++;
-				np->stats.tx_bytes += np->tx_skbuff[i]->len;
+			if (Flags & NV_TX2_LASTPACKET) {
+				skb = np->tx_skbuff[i];
+				if (Flags & (NV_TX2_RETRYERROR|NV_TX2_CARRIERLOST|NV_TX2_LATECOLLISION|
+					     NV_TX2_UNDERFLOW|NV_TX2_ERROR)) {
+					if (Flags & NV_TX2_UNDERFLOW)
+						np->stats.tx_fifo_errors++;
+					if (Flags & NV_TX2_CARRIERLOST)
+						np->stats.tx_carrier_errors++;
+					np->stats.tx_errors++;
+				} else {
+					np->stats.tx_packets++;
+					np->stats.tx_bytes += skb->len;
+				}				
+				nv_release_txskb(dev, i);
 			}
 		}
-		pci_unmap_single(np->pci_dev, np->tx_dma[i],
-					np->tx_skbuff[i]->len,
-					PCI_DMA_TODEVICE);
-		dev_kfree_skb_irq(np->tx_skbuff[i]);
-		np->tx_skbuff[i] = NULL;
 		np->nic_tx++;
 	}
 	if (np->next_tx - np->nic_tx < TX_LIMIT_START)
@@ -1076,7 +1146,7 @@ static void nv_tx_done(struct net_device
  */
 static void nv_tx_timeout(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 
 	printk(KERN_INFO "%s: Got tx_timeout. irq: %08x\n", dev->name,
@@ -1209,7 +1279,7 @@ static int nv_getlen(struct net_device *
 
 static void nv_rx_process(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u32 Flags;
 
 	for (;;) {
@@ -1364,7 +1434,7 @@ static void set_bufsize(struct net_devic
  */
 static int nv_change_mtu(struct net_device *dev, int new_mtu)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	int old_mtu;
 
 	if (new_mtu < 64 || new_mtu > np->pkt_limit)
@@ -1449,7 +1519,7 @@ static void nv_copy_mac_to_hw(struct net
  */
 static int nv_set_mac_address(struct net_device *dev, void *addr)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	struct sockaddr *macaddr = (struct sockaddr*)addr;
 
 	if(!is_valid_ether_addr(macaddr->sa_data))
@@ -1484,7 +1554,7 @@ static int nv_set_mac_address(struct net
  */
 static void nv_set_multicast(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 	u32 addr[2];
 	u32 mask[2];
@@ -1544,7 +1614,7 @@ static void nv_set_multicast(struct net_
 
 static int nv_update_linkspeed(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 	int adv, lpa;
 	int newls = np->linkspeed;
@@ -1714,7 +1784,7 @@ static void nv_link_irq(struct net_devic
 static irqreturn_t nv_nic_irq(int foo, void *data, struct pt_regs *regs)
 {
 	struct net_device *dev = (struct net_device *) data;
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 	u32 events;
 	int i;
@@ -1786,7 +1856,7 @@ static irqreturn_t nv_nic_irq(int foo, v
 static void nv_do_nic_poll(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *) data;
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 
 	disable_irq(dev->irq);
@@ -1810,7 +1880,7 @@ static void nv_poll_controller(struct ne
 
 static void nv_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	strcpy(info->driver, "forcedeth");
 	strcpy(info->version, FORCEDETH_VERSION);
 	strcpy(info->bus_info, pci_name(np->pci_dev));
@@ -1818,7 +1888,7 @@ static void nv_get_drvinfo(struct net_de
 
 static void nv_get_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	wolinfo->supported = WAKE_MAGIC;
 
 	spin_lock_irq(&np->lock);
@@ -1829,7 +1899,7 @@ static void nv_get_wol(struct net_device
 
 static int nv_set_wol(struct net_device *dev, struct ethtool_wolinfo *wolinfo)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 
 	spin_lock_irq(&np->lock);
@@ -2030,7 +2100,7 @@ static int nv_get_regs_len(struct net_de
 
 static void nv_get_regs(struct net_device *dev, struct ethtool_regs *regs, void *buf)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 	u32 *rbuf = buf;
 	int i;
@@ -2044,7 +2114,7 @@ static void nv_get_regs(struct net_devic
 
 static int nv_nway_reset(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	int ret;
 
 	spin_lock_irq(&np->lock);
@@ -2079,7 +2149,7 @@ static struct ethtool_ops ops = {
 
 static int nv_open(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base = get_hwbase(dev);
 	int ret, oom, i;
 
@@ -2215,7 +2285,7 @@ out_drain:
 
 static int nv_close(struct net_device *dev)
 {
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 	u8 __iomem *base;
 
 	spin_lock_irq(&np->lock);
@@ -2271,7 +2341,7 @@ static int __devinit nv_probe(struct pci
 	if (!dev)
 		goto out;
 
-	np = get_nvpriv(dev);
+	np = netdev_priv(dev);
 	np->pci_dev = pci_dev;
 	spin_lock_init(&np->lock);
 	SET_MODULE_OWNER(dev);
@@ -2323,6 +2393,8 @@ static int __devinit nv_probe(struct pci
 		if (pci_set_dma_mask(pci_dev, 0x0000007fffffffffULL)) {
 			printk(KERN_INFO "forcedeth: 64-bit DMA failed, using 32-bit addressing for device %s.\n",
 					pci_name(pci_dev));
+		} else {
+			dev->features |= NETIF_F_HIGHDMA;
 		}
 		np->txrxctl_bits = NVREG_TXRXCTL_DESC_3;
 	} else if (id->driver_data & DEV_HAS_LARGEDESC) {
@@ -2341,8 +2413,11 @@ static int __devinit nv_probe(struct pci
 
 	if (id->driver_data & DEV_HAS_CHECKSUM) {
 		np->txrxctl_bits |= NVREG_TXRXCTL_RXCHECK;
-		dev->features |= NETIF_F_HW_CSUM;
-	}
+		dev->features |= NETIF_F_HW_CSUM | NETIF_F_SG;
+#ifdef NETIF_F_TSO
+		dev->features |= NETIF_F_TSO;
+#endif
+ 	}
 
 	err = -ENOMEM;
 	np->base = ioremap(addr, NV_PCI_REGSZ);
@@ -2422,9 +2497,9 @@ static int __devinit nv_probe(struct pci
 	np->wolenabled = 0;
 
 	if (np->desc_ver == DESC_VER_1) {
-		np->tx_flags = NV_TX_LASTPACKET|NV_TX_VALID;
+		np->tx_flags = NV_TX_VALID;
 	} else {
-		np->tx_flags = NV_TX2_LASTPACKET|NV_TX2_VALID;
+		np->tx_flags = NV_TX2_VALID;
 	}
 	np->irqmask = NVREG_IRQMASK_WANTED;
 	if (id->driver_data & DEV_NEED_TIMERIRQ)
@@ -2513,7 +2588,7 @@ out:
 static void __devexit nv_remove(struct pci_dev *pci_dev)
 {
 	struct net_device *dev = pci_get_drvdata(pci_dev);
-	struct fe_priv *np = get_nvpriv(dev);
+	struct fe_priv *np = netdev_priv(dev);
 
 	unregister_netdev(dev);
 
---
0.99.8.GIT


--- NEW FILE 0940-gfp_t-drivers-net.txt ---
Subject: [PATCH] gfp_t: drivers/net
From: Al Viro <viro at zeniv.linux.org.uk>
Date: 1129879349 -0400

Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/cassini.c   |    4 ++--
 drivers/net/lance.c     |    4 ++--
 drivers/net/myri_sbus.c |    2 +-
 drivers/net/myri_sbus.h |    2 +-
 drivers/net/sunbmac.c   |    3 ++-
 drivers/net/sunbmac.h   |    2 +-
 6 files changed, 9 insertions(+), 8 deletions(-)

applies-to: b86e4ef9ef7ae1f54b64d19ca1e35c3607c36845
9e24974db6b01ec067c24de09588282b6a1407f0
diff --git a/drivers/net/cassini.c b/drivers/net/cassini.c
index 2e61742..50f43db 100644
--- a/drivers/net/cassini.c
+++ b/drivers/net/cassini.c
@@ -489,7 +489,7 @@ static int cas_page_free(struct cas *cp,
 /* local page allocation routines for the receive buffers. jumbo pages
  * require at least 8K contiguous and 8K aligned buffers.
  */
-static cas_page_t *cas_page_alloc(struct cas *cp, const int flags)
+static cas_page_t *cas_page_alloc(struct cas *cp, const gfp_t flags)
 {
 	cas_page_t *page;
 
@@ -561,7 +561,7 @@ static void cas_spare_free(struct cas *c
 }
 
 /* replenish spares if needed */
-static void cas_spare_recover(struct cas *cp, const int flags)
+static void cas_spare_recover(struct cas *cp, const gfp_t flags)
 {
 	struct list_head list, *elem, *tmp;
 	int needed, i;
diff --git a/drivers/net/lance.c b/drivers/net/lance.c
index b4929be..1d75ca0 100644
--- a/drivers/net/lance.c
+++ b/drivers/net/lance.c
@@ -298,7 +298,7 @@ enum {OLD_LANCE = 0, PCNET_ISA=1, PCNET_
 static unsigned char lance_need_isa_bounce_buffers = 1;
 
 static int lance_open(struct net_device *dev);
-static void lance_init_ring(struct net_device *dev, int mode);
+static void lance_init_ring(struct net_device *dev, gfp_t mode);
 static int lance_start_xmit(struct sk_buff *skb, struct net_device *dev);
 static int lance_rx(struct net_device *dev);
 static irqreturn_t lance_interrupt(int irq, void *dev_id, struct pt_regs *regs);
@@ -846,7 +846,7 @@ lance_purge_ring(struct net_device *dev)
 
 /* Initialize the LANCE Rx and Tx rings. */
 static void
-lance_init_ring(struct net_device *dev, int gfp)
+lance_init_ring(struct net_device *dev, gfp_t gfp)
 {
 	struct lance_private *lp = dev->priv;
 	int i;
diff --git a/drivers/net/myri_sbus.c b/drivers/net/myri_sbus.c
index f0996ce..6c86dca 100644
--- a/drivers/net/myri_sbus.c
+++ b/drivers/net/myri_sbus.c
@@ -277,7 +277,7 @@ static void myri_init_rings(struct myri_
 	struct recvq __iomem *rq = mp->rq;
 	struct myri_rxd __iomem *rxd = &rq->myri_rxd[0];
 	struct net_device *dev = mp->dev;
-	int gfp_flags = GFP_KERNEL;
+	gfp_t gfp_flags = GFP_KERNEL;
 	int i;
 
 	if (from_irq || in_interrupt())
diff --git a/drivers/net/myri_sbus.h b/drivers/net/myri_sbus.h
index 9391e55..47722f7 100644
--- a/drivers/net/myri_sbus.h
+++ b/drivers/net/myri_sbus.h
@@ -296,7 +296,7 @@ struct myri_eth {
 /* We use this to acquire receive skb's that we can DMA directly into. */
 #define ALIGNED_RX_SKB_ADDR(addr) \
         ((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr))
-static inline struct sk_buff *myri_alloc_skb(unsigned int length, int gfp_flags)
+static inline struct sk_buff *myri_alloc_skb(unsigned int length, gfp_t gfp_flags)
 {
 	struct sk_buff *skb;
 
diff --git a/drivers/net/sunbmac.c b/drivers/net/sunbmac.c
index f88f5e3..cfaf47c 100644
--- a/drivers/net/sunbmac.c
+++ b/drivers/net/sunbmac.c
@@ -214,7 +214,8 @@ static void bigmac_init_rings(struct big
 {
 	struct bmac_init_block *bb = bp->bmac_block;
 	struct net_device *dev = bp->dev;
-	int i, gfp_flags = GFP_KERNEL;
+	int i;
+	gfp_t gfp_flags = GFP_KERNEL;
 
 	if (from_irq || in_interrupt())
 		gfp_flags = GFP_ATOMIC;
diff --git a/drivers/net/sunbmac.h b/drivers/net/sunbmac.h
index 5674003..b0dbc51 100644
--- a/drivers/net/sunbmac.h
+++ b/drivers/net/sunbmac.h
@@ -339,7 +339,7 @@ struct bigmac {
 #define ALIGNED_RX_SKB_ADDR(addr) \
         ((((unsigned long)(addr) + (64 - 1)) & ~(64 - 1)) - (unsigned long)(addr))
 
-static inline struct sk_buff *big_mac_alloc_skb(unsigned int length, int gfp_flags)
+static inline struct sk_buff *big_mac_alloc_skb(unsigned int length, gfp_t gfp_flags)
 {
 	struct sk_buff *skb;
 
---
0.99.8.GIT


--- NEW FILE 0945-ARM-2919-1-CS8900A-ethernet-driver-modifications-for-the-Comdial-MP1000.txt ---
Subject: [PATCH] [ARM] 2919/1: CS8900A ethernet driver modifications for the Comdial MP1000
From: Jon Ringle <jon.ringle at comdial.com>
Date: 1130512778 +0100

Patch from Jon Ringle

This patch gives support for the CS8900A ethernet chip on the Comdial MP1000

Signed-off-by: Jon Ringle
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>

---

 drivers/net/Kconfig  |    2 +-
 drivers/net/cs89x0.c |   14 +++++++++++++-
 drivers/net/cs89x0.h |    2 +-
 3 files changed, 15 insertions(+), 3 deletions(-)

applies-to: c6fa01fd5a8d156b415ba9203f8ad349165de8ec
917f68f8163eb877a6d71c5b446ee236645c2944
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index c748b0e..3e1e323 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -1330,7 +1330,7 @@ config FORCEDETH
 
 config CS89x0
 	tristate "CS89x0 support"
-	depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105
+	depends on (NET_PCI && (ISA || ARCH_IXDP2X01)) || ARCH_PNX0105 || MACH_MP1000
 	---help---
 	  Support for CS89x0 chipset based Ethernet cards. If you have a
 	  network (Ethernet) card of this type, say Y and read the
diff --git a/drivers/net/cs89x0.c b/drivers/net/cs89x0.c
index a6078ad..bfdae10 100644
--- a/drivers/net/cs89x0.c
+++ b/drivers/net/cs89x0.c
@@ -182,6 +182,10 @@ static unsigned int cs8900_irq_map[] = {
 #define CIRRUS_DEFAULT_IRQ	VH_INTC_INT_NUM_CASCADED_INTERRUPT_1 /* Event inputs bank 1 - ID 35/bit 3 */
 static unsigned int netcard_portlist[] __initdata = {CIRRUS_DEFAULT_BASE, 0};
 static unsigned int cs8900_irq_map[] = {CIRRUS_DEFAULT_IRQ, 0, 0, 0};
+#elif defined(CONFIG_MACH_MP1000)
+#include <asm/arch/mp1000-seprom.h>
+static unsigned int netcard_portlist[] __initdata = {MP1000_EIO_BASE+0x300, 0};
+static unsigned int cs8900_irq_map[] = {IRQ_EINT3,0,0,0};
 #else
 static unsigned int netcard_portlist[] __initdata =
    { 0x300, 0x320, 0x340, 0x360, 0x200, 0x220, 0x240, 0x260, 0x280, 0x2a0, 0x2c0, 0x2e0, 0};
@@ -590,6 +594,10 @@ cs89x0_probe1(struct net_device *dev, in
 			cnt -= j;
 		}
 	} else
+#elif defined(CONFIG_MACH_MP1000)
+	if (1) {
+		memcpy(dev->dev_addr, get_eeprom_mac_address(), ETH_ALEN);
+	} else
 #endif
 
         if ((readreg(dev, PP_SelfST) & (EEPROM_OK | EEPROM_PRESENT)) == 
@@ -649,6 +657,10 @@ cs89x0_probe1(struct net_device *dev, in
 	if (1) {
 		printk(KERN_NOTICE "cs89x0: No EEPROM on HiCO.SH4\n");
 	} else
+#elif defined(CONFIG_MACH_MP1000)
+	if (1) {
+		lp->force |= FORCE_RJ45;
+	} else
 #endif
 	if ((readreg(dev, PP_SelfST) & EEPROM_PRESENT) == 0)
 		printk(KERN_WARNING "cs89x0: No EEPROM, relying on command line....\n");
@@ -1231,7 +1243,7 @@ net_open(struct net_device *dev)
 	else
 #endif
 	{
-#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105)
+#if !defined(CONFIG_ARCH_IXDP2X01) && !defined(CONFIG_ARCH_PNX0105) && !defined(CONFIG_MACH_MP1000)
 		if (((1 << dev->irq) & lp->irq_map) == 0) {
 			printk(KERN_ERR "%s: IRQ %d is not in our map of allowable IRQs, which is %x\n",
                                dev->name, dev->irq, lp->irq_map);
diff --git a/drivers/net/cs89x0.h b/drivers/net/cs89x0.h
index decea26..f19d1eb 100644
--- a/drivers/net/cs89x0.h
+++ b/drivers/net/cs89x0.h
@@ -16,7 +16,7 @@
 
 #include <linux/config.h>
 
-#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105)
+#if defined(CONFIG_ARCH_IXDP2X01) || defined(CONFIG_ARCH_PNX0105) || defined (CONFIG_MACH_MP1000)
 /* IXDP2401/IXDP2801 uses dword-aligned register addressing */
 #define CS89x0_PORT(reg) ((reg) * 2)
 #else
---
0.99.8.GIT


--- NEW FILE 1012-DRIVER-MODEL-Get-rid-of-the-obsolete-tri-level-suspend-resume-callbacks.txt ---
Subject: [PATCH] DRIVER MODEL: Get rid of the obsolete tri-level suspend/resume callbacks
From: Russell King <rmk at arm.linux.org.uk>
Date: 1130518376 -0700

In PM v1, all devices were called at SUSPEND_DISABLE level.  Then
all devices were called at SUSPEND_SAVE_STATE level, and finally
SUSPEND_POWER_DOWN level.  However, with PM v2, to maintain
compatibility for platform devices, I arranged for the PM v2
suspend/resume callbacks to call the old PM v1 suspend/resume
callbacks three times with each level in order so that existing
drivers continued to work.

Since this is obsolete infrastructure which is no longer necessary,
we can remove it.  Here's an (untested) patch to do exactly that.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
Signed-off-by: Greg Kroah-Hartman <gregkh at suse.de>

---

 Documentation/driver-model/driver.txt |   60 +--------------------------------
 arch/arm/common/locomo.c              |   10 +-----
 arch/arm/common/sa1111.c              |   11 +-----
 arch/arm/common/scoop.c               |   24 ++++++-------
 arch/arm/mach-pxa/corgi_ssp.c         |   24 ++++++-------
 arch/arm/mach-sa1100/neponset.c       |   28 ++++++---------
 drivers/base/platform.c               |   20 +++--------
 drivers/char/s3c2410-rtc.c            |   20 +++++------
 drivers/char/sonypi.c                 |   14 +++-----
 drivers/char/watchdog/s3c2410_wdt.c   |   34 ++++++++-----------
 drivers/hwmon/hdaps.c                 |    6 +--
 drivers/i2c/busses/i2c-s3c2410.c      |    8 ++--
 drivers/i2c/i2c-core.c                |    4 +-
 drivers/ieee1394/nodemgr.c            |    4 +-
 drivers/input/keyboard/corgikbd.c     |   22 ++++++------
 drivers/input/keyboard/spitzkbd.c     |   44 ++++++++++++------------
 drivers/input/serio/i8042.c           |   13 ++-----
 drivers/input/touchscreen/corgi_ts.c  |   38 ++++++++++-----------
 drivers/media/video/msp3400.c         |    8 ++--
 drivers/media/video/tda9887.c         |    4 +-
 drivers/media/video/tuner-core.c      |    4 +-
 drivers/mfd/mcp-sa11x0.c              |   20 +++++------
 drivers/mmc/pxamci.c                  |    8 ++--
 drivers/mmc/wbsd.c                    |    4 +-
 drivers/mtd/maps/sa1100-flash.c       |    8 ++--
 drivers/net/dm9000.c                  |    8 ++--
 drivers/net/irda/sa1100_ir.c          |    8 ++--
 drivers/net/irda/smsc-ircc2.c         |   12 +++----
 drivers/net/phy/mdio_bus.c            |   20 +++--------
 drivers/net/smc91x.c                  |    8 ++--
 drivers/pci/pcie/portdrv_core.c       |    4 +-
 drivers/pcmcia/au1000_generic.c       |   21 +-----------
 drivers/pcmcia/hd64465_ss.c           |   20 +----------
 drivers/pcmcia/i82365.c               |   20 +----------
 drivers/pcmcia/m32r_cfc.c             |   21 +-----------
 drivers/pcmcia/m32r_pcc.c             |   21 +-----------
 drivers/pcmcia/omap_cf.c              |   18 +---------
 drivers/pcmcia/pxa2xx_base.c          |   26 ++++----------
 drivers/pcmcia/sa1100_generic.c       |   20 +----------
 drivers/pcmcia/tcic.c                 |   20 +----------
 drivers/pcmcia/vrc4171_card.c         |   24 +------------
 drivers/serial/8250.c                 |   10 +-----
 drivers/serial/imx.c                  |    8 ++--
 drivers/serial/mpc52xx_uart.c         |    8 ++--
 drivers/serial/pxa.c                  |    8 ++--
 drivers/serial/s3c2410.c              |    9 ++---
 drivers/serial/sa1100.c               |    8 ++--
 drivers/serial/vr41xx_siu.c           |   10 +-----
 drivers/usb/gadget/dummy_hcd.c        |   22 ++----------
 drivers/usb/gadget/omap_udc.c         |    9 +----
 drivers/usb/gadget/pxa2xx_udc.c       |   17 ++++-----
 drivers/usb/host/isp116x-hcd.c        |   14 ++------
 drivers/usb/host/ohci-omap.c          |   10 +-----
 drivers/usb/host/ohci-pxa27x.c        |    4 +-
 drivers/usb/host/sl811-hcd.c          |   10 +-----
 drivers/video/backlight/corgi_bl.c    |   10 ++----
 drivers/video/imxfb.c                 |   10 ++----
 drivers/video/pxafb.c                 |   10 ++----
 drivers/video/s1d13xxxfb.c            |    7 +---
 drivers/video/s3c2410fb.c             |   29 +++++++---------
 drivers/video/sa1100fb.c              |   10 ++----
 drivers/video/w100fb.c                |   48 +++++++++++++-------------
 include/linux/device.h                |   17 +--------
 sound/arm/pxa2xx-ac97.c               |    8 ++--
 sound/core/init.c                     |   14 ++------
 sound/pci/ac97/ac97_bus.c             |    6 ++-
 66 files changed, 330 insertions(+), 697 deletions(-)

applies-to: 81caf424dcae1b2231946a9cebd83d5b067f32b4
9480e307cd88ef09ec9294c7d97ebec18e6d2221
diff --git a/Documentation/driver-model/driver.txt b/Documentation/driver-model/driver.txt
index fabaca1..7c26bfa 100644
--- a/Documentation/driver-model/driver.txt
+++ b/Documentation/driver-model/driver.txt
@@ -196,67 +196,11 @@ it into a supported low-power state.
 
 	int	(*suspend)	(struct device * dev, pm_message_t state, u32 level);
 
-suspend is called to put the device in a low power state. There are
-several stages to successfully suspending a device, which is denoted in
-the @level parameter. Breaking the suspend transition into several
-stages affords the platform flexibility in performing device power
-management based on the requirements of the system and the
-user-defined policy.
-
-SUSPEND_NOTIFY notifies the device that a suspend transition is about
-to happen. This happens on system power state transitions to verify
-that all devices can successfully suspend.
-
-A driver may choose to fail on this call, which should cause the
-entire suspend transition to fail. A driver should fail only if it
-knows that the device will not be able to be resumed properly when the
-system wakes up again. It could also fail if it somehow determines it
-is in the middle of an operation too important to stop.
-
-SUSPEND_DISABLE tells the device to stop I/O transactions. When it
-stops transactions, or what it should do with unfinished transactions
-is a policy of the driver. After this call, the driver should not
-accept any other I/O requests.
-
-SUSPEND_SAVE_STATE tells the device to save the context of the
-hardware. This includes any bus-specific hardware state and
-device-specific hardware state. A pointer to this saved state can be
-stored in the device's saved_state field.
-
-SUSPEND_POWER_DOWN tells the driver to place the device in the low
-power state requested. 
-
-Whether suspend is called with a given level is a policy of the
-platform. Some levels may be omitted; drivers must not assume the
-reception of any level. However, all levels must be called in the
-order above; i.e. notification will always come before disabling;
-disabling the device will come before suspending the device.
-
-All calls are made with interrupts enabled, except for the
-SUSPEND_POWER_DOWN level.
+suspend is called to put the device in a low power state.
 
 	int	(*resume)	(struct device * dev, u32 level);
 
-Resume is used to bring a device back from a low power state. Like the
-suspend transition, it happens in several stages. 
-
-RESUME_POWER_ON tells the driver to set the power state to the state
-before the suspend call (The device could have already been in a low
-power state before the suspend call to put in a lower power state). 
-
-RESUME_RESTORE_STATE tells the driver to restore the state saved by
-the SUSPEND_SAVE_STATE suspend call. 
-
-RESUME_ENABLE tells the driver to start accepting I/O transactions
-again. Depending on driver policy, the device may already have pending
-I/O requests. 
-
-RESUME_POWER_ON is called with interrupts disabled. The other resume
-levels are called with interrupts enabled. 
-
-As with the various suspend stages, the driver must not assume that
-any other resume calls have been or will be made. Each call should be
-self-contained and not dependent on any external state.
+Resume is used to bring a device back from a low power state.
 
 
 Attributes
diff --git a/arch/arm/common/locomo.c b/arch/arm/common/locomo.c
index e8053d1..5cdb412 100644
--- a/arch/arm/common/locomo.c
+++ b/arch/arm/common/locomo.c
@@ -550,15 +550,12 @@ struct locomo_save_data {
 	u16	LCM_SPIMD;
 };
 
-static int locomo_suspend(struct device *dev, pm_message_t state, u32 level)
+static int locomo_suspend(struct device *dev, pm_message_t state)
 {
 	struct locomo *lchip = dev_get_drvdata(dev);
 	struct locomo_save_data *save;
 	unsigned long flags;
 
-	if (level != SUSPEND_DISABLE)
-		return 0;
-
 	save = kmalloc(sizeof(struct locomo_save_data), GFP_KERNEL);
 	if (!save)
 		return -ENOMEM;
@@ -597,16 +594,13 @@ static int locomo_suspend(struct device 
 	return 0;
 }
 
-static int locomo_resume(struct device *dev, u32 level)
+static int locomo_resume(struct device *dev)
 {
 	struct locomo *lchip = dev_get_drvdata(dev);
 	struct locomo_save_data *save;
 	unsigned long r;
 	unsigned long flags;
 	
-	if (level != RESUME_ENABLE)
-		return 0;
[...2082 lines suppressed...]
--- a/drivers/video/w100fb.c
+++ b/drivers/video/w100fb.c
@@ -438,36 +438,34 @@ static void w100fb_restore_vidmem(struct
 	}
 }
 
-static int w100fb_suspend(struct device *dev, pm_message_t state, uint32_t level)
+static int w100fb_suspend(struct device *dev, pm_message_t state)
 {
-	if (level == SUSPEND_POWER_DOWN) {
-		struct fb_info *info = dev_get_drvdata(dev);
-		struct w100fb_par *par=info->par;
-		struct w100_tg_info *tg = par->mach->tg;
-
-		w100fb_save_vidmem(par);
-		if(tg && tg->suspend)
-			tg->suspend(par);
-		w100_suspend(W100_SUSPEND_ALL);
-		par->blanked = 1;
-	}
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+	struct w100_tg_info *tg = par->mach->tg;
+
+	w100fb_save_vidmem(par);
+	if(tg && tg->suspend)
+		tg->suspend(par);
+	w100_suspend(W100_SUSPEND_ALL);
+	par->blanked = 1;
+
 	return 0;
 }
 
-static int w100fb_resume(struct device *dev, uint32_t level)
+static int w100fb_resume(struct device *dev)
 {
-	if (level == RESUME_POWER_ON) {
-		struct fb_info *info = dev_get_drvdata(dev);
-		struct w100fb_par *par=info->par;
-		struct w100_tg_info *tg = par->mach->tg;
-
-		w100_hw_init(par);
-		w100fb_activate_var(par);
-		w100fb_restore_vidmem(par);
-		if(tg && tg->resume)
-			tg->resume(par);
-		par->blanked = 0;
-	}
+	struct fb_info *info = dev_get_drvdata(dev);
+	struct w100fb_par *par=info->par;
+	struct w100_tg_info *tg = par->mach->tg;
+
+	w100_hw_init(par);
+	w100fb_activate_var(par);
+	w100fb_restore_vidmem(par);
+	if(tg && tg->resume)
+		tg->resume(par);
+	par->blanked = 0;
+
 	return 0;
 }
 #else
diff --git a/include/linux/device.h b/include/linux/device.h
index 10ab780..a9e72ac 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -28,19 +28,6 @@
 #define BUS_ID_SIZE		KOBJ_NAME_LEN
 
 
-enum {
-	SUSPEND_NOTIFY,
-	SUSPEND_SAVE_STATE,
-	SUSPEND_DISABLE,
-	SUSPEND_POWER_DOWN,
-};
-
-enum {
-	RESUME_POWER_ON,
-	RESUME_RESTORE_STATE,
-	RESUME_ENABLE,
-};
-
 struct device;
 struct device_driver;
 struct class;
@@ -115,8 +102,8 @@ struct device_driver {
 	int	(*probe)	(struct device * dev);
 	int	(*remove)	(struct device * dev);
 	void	(*shutdown)	(struct device * dev);
-	int	(*suspend)	(struct device * dev, pm_message_t state, u32 level);
-	int	(*resume)	(struct device * dev, u32 level);
+	int	(*suspend)	(struct device * dev, pm_message_t state);
+	int	(*resume)	(struct device * dev);
 };
 
 
diff --git a/sound/arm/pxa2xx-ac97.c b/sound/arm/pxa2xx-ac97.c
index 38b20ef..877bb00 100644
--- a/sound/arm/pxa2xx-ac97.c
+++ b/sound/arm/pxa2xx-ac97.c
@@ -275,23 +275,23 @@ static int pxa2xx_ac97_do_resume(snd_car
 	return 0;
 }
 
-static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state, u32 level)
+static int pxa2xx_ac97_suspend(struct device *_dev, pm_message_t state)
 {
 	snd_card_t *card = dev_get_drvdata(_dev);
 	int ret = 0;
 
-	if (card && level == SUSPEND_DISABLE)
+	if (card)
 		ret = pxa2xx_ac97_do_suspend(card, PMSG_SUSPEND);
 
 	return ret;
 }
 
-static int pxa2xx_ac97_resume(struct device *_dev, u32 level)
+static int pxa2xx_ac97_resume(struct device *_dev)
 {
 	snd_card_t *card = dev_get_drvdata(_dev);
 	int ret = 0;
 
-	if (card && level == RESUME_ENABLE)
+	if (card)
 		ret = pxa2xx_ac97_do_resume(card);
 
 	return ret;
diff --git a/sound/core/init.c b/sound/core/init.c
index c72a791..59202de 100644
--- a/sound/core/init.c
+++ b/sound/core/init.c
@@ -676,8 +676,8 @@ struct snd_generic_device {
 #define SND_GENERIC_NAME	"snd_generic"
 
 #ifdef CONFIG_PM
-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level);
-static int snd_generic_resume(struct device *dev, u32 level);
+static int snd_generic_suspend(struct device *dev, pm_message_t state);
+static int snd_generic_resume(struct device *dev);
 #endif
 
 /* initialized in sound.c */
@@ -818,13 +818,10 @@ int snd_card_set_pm_callback(snd_card_t 
 
 #ifdef CONFIG_SND_GENERIC_DRIVER
 /* suspend/resume callbacks for snd_generic platform device */
-static int snd_generic_suspend(struct device *dev, pm_message_t state, u32 level)
+static int snd_generic_suspend(struct device *dev, pm_message_t state)
 {
 	snd_card_t *card;
 
-	if (level != SUSPEND_DISABLE)
-		return 0;
-
 	card = get_snd_generic_card(dev);
 	if (card->power_state == SNDRV_CTL_POWER_D3hot)
 		return 0;
@@ -834,13 +831,10 @@ static int snd_generic_suspend(struct de
 	return 0;
 }
 
-static int snd_generic_resume(struct device *dev, u32 level)
+static int snd_generic_resume(struct device *dev)
 {
 	snd_card_t *card;
 
-	if (level != RESUME_ENABLE)
-		return 0;
-
 	card = get_snd_generic_card(dev);
 	if (card->power_state == SNDRV_CTL_POWER_D0)
 		return 0;
diff --git a/sound/pci/ac97/ac97_bus.c b/sound/pci/ac97/ac97_bus.c
index becbc42..ec70fad 100644
--- a/sound/pci/ac97/ac97_bus.c
+++ b/sound/pci/ac97/ac97_bus.c
@@ -31,7 +31,8 @@ static int ac97_bus_suspend(struct devic
 	int ret = 0;
 
 	if (dev->driver && dev->driver->suspend)
-		ret = dev->driver->suspend(dev, state, SUSPEND_POWER_DOWN);
+		ret = dev->driver->suspend(dev, state);
+
 	return ret;
 }
 
@@ -40,7 +41,8 @@ static int ac97_bus_resume(struct device
 	int ret = 0;
 
 	if (dev->driver && dev->driver->resume)
-		ret = dev->driver->resume(dev, RESUME_POWER_ON);
+		ret = dev->driver->resume(dev);
+
 	return ret;
 }
 
---
0.99.8.GIT


--- NEW FILE 1038-tg3-add-5714-5715-support.txt ---
Subject: [PATCH] tg3: add 5714/5715 support
From: Michael Chan <mchan at broadcom.com>
Date: 1130366812 -0700

Add complete support for 5714/5715. These chips are very similar to
5780 so the changes are very trivial. A TG3_FLG2_5780_CLASS flag is
added to identify these chips.

Signed-off-by: Michael Chan <mchan at broadcom.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/tg3.c       |   39 +++++++++++++++++++++++++--------------
 drivers/net/tg3.h       |   11 +++++++++--
 include/linux/pci_ids.h |    2 ++
 3 files changed, 36 insertions(+), 16 deletions(-)

applies-to: 73924189ef46511301d004946fbdd9937b00c484
a4e2b347848bf626b822599329933887dc90e50f
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 1802c3b..cf2204f 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -219,6 +219,10 @@ static struct pci_device_id tg3_pci_tbl[
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5753F,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5714,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5715,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0UL },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_TIGON3_5780S,
@@ -570,7 +574,7 @@ static void tg3_switch_clocks(struct tg3
 	u32 clock_ctrl = tr32(TG3PCI_CLOCK_CTRL);
 	u32 orig_clock_ctrl;
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+	if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
 		return;
 
 	orig_clock_ctrl = clock_ctrl;
@@ -1210,7 +1214,7 @@ static int tg3_set_power_state(struct tg
 		     CLOCK_CTRL_ALTCLK |
 		     CLOCK_CTRL_PWRDOWN_PLL133);
 		udelay(40);
-	} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+	} else if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
 		/* do nothing */
 	} else if (!((tp->tg3_flags2 & TG3_FLG2_5750_PLUS) &&
 		     (tp->tg3_flags & TG3_FLAG_ENABLE_ASF))) {
@@ -3712,14 +3716,14 @@ static inline void tg3_set_mtu(struct ne
 	dev->mtu = new_mtu;
 
 	if (new_mtu > ETH_DATA_LEN) {
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+		if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
 			tp->tg3_flags2 &= ~TG3_FLG2_TSO_CAPABLE;
 			ethtool_op_set_tso(dev, 0);
 		}
 		else
 			tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
 	} else {
-		if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+		if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
 			tp->tg3_flags2 |= TG3_FLG2_TSO_CAPABLE;
 		tp->tg3_flags &= ~TG3_FLAG_JUMBO_RING_ENABLE;
 	}
@@ -3850,7 +3854,7 @@ static void tg3_init_rings(struct tg3 *t
 	memset(tp->tx_ring, 0, TG3_TX_RING_BYTES);
 
 	tp->rx_pkt_buf_sz = RX_PKT_BUF_SZ;
-	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) &&
+	if ((tp->tg3_flags2 & TG3_FLG2_5780_CLASS) &&
 	    (tp->dev->mtu > ETH_DATA_LEN))
 		tp->rx_pkt_buf_sz = RX_JUMBO_PKT_BUF_SZ;
 
@@ -4347,7 +4351,7 @@ static int tg3_chip_reset(struct tg3 *tp
 	val &= ~PCIX_CAPS_RELAXED_ORDERING;
 	pci_write_config_dword(tp->pdev, TG3PCI_X_CAPS, val);
 
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+	if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS) {
 		u32 val;
 
 		/* Chip reset on 5780 will reset MSI enable bit,
@@ -6003,7 +6007,7 @@ static int tg3_reset_hw(struct tg3 *tp)
 	tw32(MAC_RCV_VALUE_1, 0xffffffff & RCV_RULE_DISABLE_MASK);
 
 	if ((tp->tg3_flags2 & TG3_FLG2_5705_PLUS) &&
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780))
+	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
 		limit = 8;
 	else
 		limit = 16;
@@ -7237,7 +7241,7 @@ static int tg3_get_settings(struct net_d
 		cmd->supported |= (SUPPORTED_1000baseT_Half |
 				   SUPPORTED_1000baseT_Full);
 
-	if (!(tp->tg3_flags2 & TG3_FLG2_PHY_SERDES))
+	if (!(tp->tg3_flags2 & TG3_FLG2_ANY_SERDES))
 		cmd->supported |= (SUPPORTED_100baseT_Half |
 				  SUPPORTED_100baseT_Full |
 				  SUPPORTED_10baseT_Half |
@@ -8380,7 +8384,7 @@ static void __devinit tg3_get_nvram_info
 	}
 
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750) ||
-	    (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)) {
+	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
 		switch (nvcfg1 & NVRAM_CFG1_VENDOR_MASK) {
 			case FLASH_VENDOR_ATMEL_FLASH_BUFFERED:
 				tp->nvram_jedecnum = JEDEC_ATMEL;
@@ -8980,7 +8984,7 @@ static void __devinit tg3_get_eeprom_hw_
 
 		tp->phy_id = eeprom_phy_id;
 		if (eeprom_phy_serdes) {
-			if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+			if (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)
 				tp->tg3_flags2 |= TG3_FLG2_MII_SERDES;
 			else
 				tp->tg3_flags2 |= TG3_FLG2_PHY_SERDES;
@@ -9393,8 +9397,11 @@ static int __devinit tg3_get_invariants(
 	}
 
 	/* Find msi capability. */
-	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780 ||
+	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
+		tp->tg3_flags2 |= TG3_FLG2_5780_CLASS;
 		tp->msi_cap = pci_find_capability(tp->pdev, PCI_CAP_ID_MSI);
+	}
 
 	/* Initialize misc host control in PCI block. */
 	tp->misc_host_ctrl |= (misc_ctrl_reg &
@@ -9412,7 +9419,7 @@ static int __devinit tg3_get_invariants(
 
 	if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5750 ||
 	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5752 ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780)
+	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
 		tp->tg3_flags2 |= TG3_FLG2_5750_PLUS;
 
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5705) ||
@@ -9607,7 +9614,7 @@ static int __devinit tg3_get_invariants(
 	 * ether_setup() via the alloc_etherdev() call
 	 */
 	if (tp->dev->mtu > ETH_DATA_LEN &&
-	    GET_ASIC_REV(tp->pci_chip_rev_id) != ASIC_REV_5780)
+	    !(tp->tg3_flags2 & TG3_FLG2_5780_CLASS))
 		tp->tg3_flags |= TG3_FLAG_JUMBO_RING_ENABLE;
 
 	/* Determine WakeOnLan speed to use. */
@@ -9830,7 +9837,7 @@ static int __devinit tg3_get_device_addr
 	mac_offset = 0x7c;
 	if ((GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5704 &&
 	     !(tp->tg3_flags & TG3_FLG2_SUN_570X)) ||
-	    GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
+	    (tp->tg3_flags2 & TG3_FLG2_5780_CLASS)) {
 		if (tr32(TG3PCI_DUAL_MAC_CTRL) & DUAL_MAC_CTRL_ID)
 			mac_offset = 0xcc;
 		if (tg3_nvram_lock(tp))
@@ -10148,6 +10155,9 @@ static int __devinit tg3_test_dma(struct
 		} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5780) {
 			/* 5780 always in PCIX mode */
 			tp->dma_rwctrl |= 0x00144000;
+		} else if (GET_ASIC_REV(tp->pci_chip_rev_id) == ASIC_REV_5714) {
+			/* 5714 always in PCIX mode */
+			tp->dma_rwctrl |= 0x00148000;
 		} else {
 			tp->dma_rwctrl |= 0x001b000f;
 		}
@@ -10347,6 +10357,7 @@ static char * __devinit tg3_phy_string(s
 	case PHY_ID_BCM5705:	return "5705";
 	case PHY_ID_BCM5750:	return "5750";
 	case PHY_ID_BCM5752:	return "5752";
+	case PHY_ID_BCM5714:	return "5714";
 	case PHY_ID_BCM5780:	return "5780";
 	case PHY_ID_BCM8002:	return "8002/serdes";
 	case 0:			return "serdes";
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 2e733c6..456ef2b 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -137,6 +137,7 @@
 #define   ASIC_REV_5750			 0x04
 #define   ASIC_REV_5752			 0x06
 #define   ASIC_REV_5780			 0x08
+#define   ASIC_REV_5714			 0x09
 #define  GET_CHIP_REV(CHIP_REV_ID)	((CHIP_REV_ID) >> 8)
 #define   CHIPREV_5700_AX		 0x70
 #define   CHIPREV_5700_BX		 0x71
@@ -531,6 +532,8 @@
 #define  MAC_SERDES_CFG_EDGE_SELECT	 0x00001000
 #define MAC_SERDES_STAT			0x00000594
 /* 0x598 --> 0x5b0 unused */
+#define SERDES_RX_CTRL			0x000005b0	/* 5780/5714 only */
+#define  SERDES_RX_SIG_DETECT		 0x00000400
 #define SG_DIG_CTRL			0x000005b0
 #define  SG_DIG_USING_HW_AUTONEG	 0x80000000
 #define  SG_DIG_SOFT_RESET		 0x40000000
@@ -1329,6 +1332,8 @@
 #define  GRC_LCLCTRL_CLEARINT		0x00000002
 #define  GRC_LCLCTRL_SETINT		0x00000004
 #define  GRC_LCLCTRL_INT_ON_ATTN	0x00000008
+#define  GRC_LCLCTRL_USE_SIG_DETECT	0x00000010	/* 5714/5780 only */
+#define  GRC_LCLCTRL_USE_EXT_SIG_DETECT	0x00000020	/* 5714/5780 only */
 #define  GRC_LCLCTRL_GPIO_INPUT3	0x00000020
 #define  GRC_LCLCTRL_GPIO_OE3		0x00000040
 #define  GRC_LCLCTRL_GPIO_OUTPUT3	0x00000080
@@ -2175,6 +2180,7 @@ struct tg3 {
 					TG3_FLG2_MII_SERDES)
 #define TG3_FLG2_PARALLEL_DETECT	0x01000000
 #define TG3_FLG2_ICH_WORKAROUND		0x02000000
+#define TG3_FLG2_5780_CLASS		0x04000000
 
 	u32				split_mode_max_reqs;
 #define SPLIT_MODE_5704_MAX_REQ		3
@@ -2222,6 +2228,7 @@ struct tg3 {
 #define PHY_ID_BCM5705			0x600081a0
 #define PHY_ID_BCM5750			0x60008180
 #define PHY_ID_BCM5752			0x60008100
+#define PHY_ID_BCM5714			0x60008340
 #define PHY_ID_BCM5780			0x60008350
 #define PHY_ID_BCM8002			0x60010140
 #define PHY_ID_INVALID			0xffffffff
@@ -2246,8 +2253,8 @@ struct tg3 {
 	 (X) == PHY_ID_BCM5411 || (X) == PHY_ID_BCM5701 || \
 	 (X) == PHY_ID_BCM5703 || (X) == PHY_ID_BCM5704 || \
 	 (X) == PHY_ID_BCM5705 || (X) == PHY_ID_BCM5750 || \
-	 (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5780 || \
-	 (X) == PHY_ID_BCM8002)
+	 (X) == PHY_ID_BCM5752 || (X) == PHY_ID_BCM5714 || \
+	 (X) == PHY_ID_BCM5780 || (X) == PHY_ID_BCM8002)
 
 	struct tg3_hw_stats		*hw_stats;
 	dma_addr_t			stats_mapping;
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 71834f0..d6865bb 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -2165,11 +2165,13 @@
 #define PCI_DEVICE_ID_TIGON3_5721	0x1659
 #define PCI_DEVICE_ID_TIGON3_5705M	0x165d
 #define PCI_DEVICE_ID_TIGON3_5705M_2	0x165e
+#define PCI_DEVICE_ID_TIGON3_5714	0x1668
 #define PCI_DEVICE_ID_TIGON3_5780	0x166a
 #define PCI_DEVICE_ID_TIGON3_5780S	0x166b
 #define PCI_DEVICE_ID_TIGON3_5705F	0x166e
 #define PCI_DEVICE_ID_TIGON3_5750	0x1676
 #define PCI_DEVICE_ID_TIGON3_5751	0x1677
+#define PCI_DEVICE_ID_TIGON3_5715	0x1678
 #define PCI_DEVICE_ID_TIGON3_5750M	0x167c
 #define PCI_DEVICE_ID_TIGON3_5751M	0x167d
 #define PCI_DEVICE_ID_TIGON3_5751F	0x167e
---
0.99.8.GIT


--- NEW FILE 1039-tg3-fix-ASF-heartbeat.txt ---
Subject: [PATCH] tg3: fix ASF heartbeat
From: Michael Chan <mchan at broadcom.com>
Date: 1130366915 -0700

Change the ASF heart beat to 5 seconds for faster detection of system
crash. The driver sends the heartbeat every 2 seconds and the ASF
firmware will timeout and reset the device if no heartbeat is received
after 5 seconds. The old scheme of 2 minutes is ineffective.

tg3_write_mem_fast() is added to speed up the IO to send the heartbeat.
When no workaround is needed, it will use direct MMIO to memory space
to write to memory.

Signed-off-by: Michael Chan <mchan at broadcom.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/tg3.c |   21 ++++++++++++++++-----
 drivers/net/tg3.h |    1 +
 2 files changed, 17 insertions(+), 5 deletions(-)

applies-to: 414564393157868b8c6d708bfb2c750cf49b1f6b
28fbef78a420acdea20570d31f3bdcbfa0cac0d2
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index cf2204f..479be21 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -470,6 +470,15 @@ static void tg3_write_mem(struct tg3 *tp
 	spin_unlock_irqrestore(&tp->indirect_lock, flags);
 }
 
+static void tg3_write_mem_fast(struct tg3 *tp, u32 off, u32 val)
+{
+	/* If no workaround is needed, write to mem space directly */
+	if (tp->write32 != tg3_write_indirect_reg32)
+		tw32(NIC_SRAM_WIN_BASE + off, val);
+	else
+		tg3_write_mem(tp, off, val);
+}
+
 static void tg3_read_mem(struct tg3 *tp, u32 off, u32 *val)
 {
 	unsigned long flags;
@@ -6195,14 +6204,16 @@ static void tg3_timer(unsigned long __op
 		tp->timer_counter = tp->timer_multiplier;
 	}
 
-	/* Heartbeat is only sent once every 120 seconds.  */
+	/* Heartbeat is only sent once every 2 seconds.  */
 	if (!--tp->asf_counter) {
 		if (tp->tg3_flags & TG3_FLAG_ENABLE_ASF) {
 			u32 val;
 
-			tg3_write_mem(tp, NIC_SRAM_FW_CMD_MBOX, FWCMD_NICDRV_ALIVE);
-			tg3_write_mem(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
-			tg3_write_mem(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 3);
+			tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_MBOX,
+					   FWCMD_NICDRV_ALIVE2);
+			tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_LEN_MBOX, 4);
+			/* 5 seconds timeout */
+			tg3_write_mem_fast(tp, NIC_SRAM_FW_CMD_DATA_MBOX, 5);
 			val = tr32(GRC_RX_CPU_EVENT);
 			val |= (1 << 14);
 			tw32(GRC_RX_CPU_EVENT, val);
@@ -6413,7 +6424,7 @@ static int tg3_open(struct net_device *d
 		tp->timer_counter = tp->timer_multiplier =
 			(HZ / tp->timer_offset);
 		tp->asf_counter = tp->asf_multiplier =
-			((HZ / tp->timer_offset) * 120);
+			((HZ / tp->timer_offset) * 2);
 
 		init_timer(&tp->timer);
 		tp->timer.expires = jiffies + tp->timer_offset;
diff --git a/drivers/net/tg3.h b/drivers/net/tg3.h
index 456ef2b..fb7e2a5 100644
--- a/drivers/net/tg3.h
+++ b/drivers/net/tg3.h
@@ -1512,6 +1512,7 @@
 #define  FWCMD_NICDRV_IPV6ADDR_CHG	 0x00000004
 #define  FWCMD_NICDRV_FIX_DMAR		 0x00000005
 #define  FWCMD_NICDRV_FIX_DMAW		 0x00000006
+#define  FWCMD_NICDRV_ALIVE2		 0x0000000d
 #define NIC_SRAM_FW_CMD_LEN_MBOX	0x00000b7c
 #define NIC_SRAM_FW_CMD_DATA_MBOX	0x00000b80
 #define NIC_SRAM_FW_ASF_STATUS_MBOX	0x00000c00
---
0.99.8.GIT


--- NEW FILE 1040-tg3-update-version-and-minor-fixes.txt ---
Subject: [PATCH] tg3: update version and minor fixes
From: Michael Chan <mchan at broadcom.com>
Date: 1130366991 -0700

Update version and reldate and add more sanity checking to
tg3_set_settings().

Signed-off-by: Gary Zambrano <zambrano at broadcom.com>
Signed-off-by: Michael Chan <mchan at broadcom.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/tg3.c |   18 ++++++++++++++----
 1 files changed, 14 insertions(+), 4 deletions(-)

applies-to: ef68381a6e776a802038e39529e89a0d1390fae0
37ff238d68683d42e7363eee3303773906c336d9
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 479be21..551c944 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -67,8 +67,8 @@
 
 #define DRV_MODULE_NAME		"tg3"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"3.42"
-#define DRV_MODULE_RELDATE	"Oct 3, 2005"
+#define DRV_MODULE_VERSION	"3.43"
+#define DRV_MODULE_RELDATE	"Oct 24, 2005"
 
 #define TG3_DEF_MAC_MODE	0
 #define TG3_DEF_RX_MODE		0
@@ -7279,7 +7279,7 @@ static int tg3_set_settings(struct net_d
 {
 	struct tg3 *tp = netdev_priv(dev);
   
-	if (tp->tg3_flags2 & TG3_FLG2_PHY_SERDES) {
+	if (tp->tg3_flags2 & TG3_FLG2_ANY_SERDES) { 
 		/* These are the only valid advertisement bits allowed.  */
 		if (cmd->autoneg == AUTONEG_ENABLE &&
 		    (cmd->advertising & ~(ADVERTISED_1000baseT_Half |
@@ -7287,7 +7287,17 @@ static int tg3_set_settings(struct net_d
 					  ADVERTISED_Autoneg |
 					  ADVERTISED_FIBRE)))
 			return -EINVAL;
-	}
+		/* Fiber can only do SPEED_1000.  */
+		else if ((cmd->autoneg != AUTONEG_ENABLE) &&
+			 (cmd->speed != SPEED_1000))
+			return -EINVAL;
+	/* Copper cannot force SPEED_1000.  */
+	} else if ((cmd->autoneg != AUTONEG_ENABLE) &&
+		   (cmd->speed == SPEED_1000))
+		return -EINVAL;
+	else if ((cmd->speed == SPEED_1000) &&
+		 (tp->tg3_flags2 & TG3_FLAG_10_100_ONLY))
+		return -EINVAL;
 
 	tg3_full_lock(tp, 0);
 
---
0.99.8.GIT


--- NEW FILE 1041-ibmveth-fix-bonding.txt ---
Subject: [PATCH] ibmveth fix bonding
From: Santiago Leon <santil at us.ibm.com>
Date: 1130345213 -0600

This patch updates dev->trans_start and dev->last_rx so that the ibmveth
driver can be used with the ARP monitor in the bonding driver.

Signed-off-by: Santiago Leon <santil at us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/ibmveth.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: 45a016abbed939ee11427941b7036f6cfeca20d3
0abe791e94033b727f2b55670c2966f3d3d3cf70
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index a2c4dd4..5617bec 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -725,6 +725,7 @@ static int ibmveth_start_xmit(struct sk_
 	} else {
 		adapter->stats.tx_packets++;
 		adapter->stats.tx_bytes += skb->len;
+		netdev->trans_start = jiffies;
 	}
 
 	do {
@@ -776,6 +777,7 @@ static int ibmveth_poll(struct net_devic
 				adapter->stats.rx_packets++;
 				adapter->stats.rx_bytes += length;
 				frames_processed++;
+				netdev->last_rx = jiffies;
 			}
 		} else {
 			more_work = 0;
---
0.99.8.GIT


--- NEW FILE 1042-ibmveth-fix-buffer-pool-management.txt ---
Subject: [PATCH] ibmveth fix buffer pool management
From: Santiago Leon <santil at us.ibm.com>
Date: 1130345221 -0600

This patch changes the way the ibmveth driver handles the receive
buffers.  The old code mallocs and maps all the buffers in the pools
regardless of MTU size and it also limits the number of buffer pools to
three. This patch makes the driver malloc and map the buffers necessary
to support the current MTU. It also changes the hardcoded names of the
buffer pool number, size, and elements to arrays to make it easier to
change (with the hope of making them runtime parameters in the future).

Signed-off-by: Santiago Leon <santil at us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/ibmveth.c |  102 ++++++++++++++++++++++++++++++++++++-------------
 drivers/net/ibmveth.h |   18 +++++----
 2 files changed, 85 insertions(+), 35 deletions(-)

applies-to: 7fe7e9dffdcb5822537a5b03c7064667e05426e6
b6d35182fe62e57d368062adcc880ca35119d88e
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 5617bec..d985b80 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -97,6 +97,7 @@ static void ibmveth_proc_register_adapte
 static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
 static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
 static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*);
+static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter);
 
 #ifdef CONFIG_PROC_FS
 #define IBMVETH_PROC_DIR "net/ibmveth"
@@ -181,6 +182,7 @@ static int ibmveth_alloc_buffer_pool(str
 	atomic_set(&pool->available, 0);
 	pool->producer_index = 0;
 	pool->consumer_index = 0;
+	pool->active = 0;
 
 	return 0;
 }
@@ -258,9 +260,14 @@ static void ibmveth_replenish_buffer_poo
 /* check if replenishing is needed.  */
 static inline int ibmveth_is_replenishing_needed(struct ibmveth_adapter *adapter)
 {
-	return ((atomic_read(&adapter->rx_buff_pool[0].available) < adapter->rx_buff_pool[0].threshold) ||
-		(atomic_read(&adapter->rx_buff_pool[1].available) < adapter->rx_buff_pool[1].threshold) ||
-		(atomic_read(&adapter->rx_buff_pool[2].available) < adapter->rx_buff_pool[2].threshold));
+	int i;
+
+	for(i = 0; i < IbmVethNumBufferPools; i++)
+		if(adapter->rx_buff_pool[i].active &&
+		  (atomic_read(&adapter->rx_buff_pool[i].available) <
+		   adapter->rx_buff_pool[i].threshold))
+			return 1;
+	return 0;
 }
 
 /* kick the replenish tasklet if we need replenishing and it isn't already running */
@@ -275,11 +282,14 @@ static inline void ibmveth_schedule_repl
 /* replenish tasklet routine */
 static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) 
 {
+	int i;
+
 	adapter->replenish_task_cycles++;
 
-	ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[0]);
-	ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[1]);
-	ibmveth_replenish_buffer_pool(adapter, &adapter->rx_buff_pool[2]);
+	for(i = 0; i < IbmVethNumBufferPools; i++)
+		if(adapter->rx_buff_pool[i].active)
+			ibmveth_replenish_buffer_pool(adapter, 
+						     &adapter->rx_buff_pool[i]);
 
 	adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
 
@@ -321,6 +331,7 @@ static void ibmveth_free_buffer_pool(str
 		kfree(pool->skbuff);
 		pool->skbuff = NULL;
 	}
+	pool->active = 0;
 }
 
 /* remove a buffer from a pool */
@@ -379,6 +390,12 @@ static void ibmveth_rxq_recycle_buffer(s
 	ibmveth_assert(pool < IbmVethNumBufferPools);
 	ibmveth_assert(index < adapter->rx_buff_pool[pool].size);
 
+	if(!adapter->rx_buff_pool[pool].active) {
+		ibmveth_rxq_harvest_buffer(adapter);
+		ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[pool]);
+		return;
+	}
+
 	desc.desc = 0;
 	desc.fields.valid = 1;
 	desc.fields.length = adapter->rx_buff_pool[pool].buff_size;
@@ -409,6 +426,8 @@ static inline void ibmveth_rxq_harvest_b
 
 static void ibmveth_cleanup(struct ibmveth_adapter *adapter)
 {
+	int i;
+
 	if(adapter->buffer_list_addr != NULL) {
 		if(!dma_mapping_error(adapter->buffer_list_dma)) {
 			dma_unmap_single(&adapter->vdev->dev,
@@ -443,26 +462,24 @@ static void ibmveth_cleanup(struct ibmve
 		adapter->rx_queue.queue_addr = NULL;
 	}
 
-	ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[0]);
-	ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[1]);
-	ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[2]);
+	for(i = 0; i<IbmVethNumBufferPools; i++)
+		ibmveth_free_buffer_pool(adapter, &adapter->rx_buff_pool[i]);
 }
 
 static int ibmveth_open(struct net_device *netdev)
 {
 	struct ibmveth_adapter *adapter = netdev->priv;
 	u64 mac_address = 0;
-	int rxq_entries;
+	int rxq_entries = 1;
 	unsigned long lpar_rc;
 	int rc;
 	union ibmveth_buf_desc rxq_desc;
+	int i;
 
 	ibmveth_debug_printk("open starting\n");
 
-	rxq_entries =
-		adapter->rx_buff_pool[0].size +
-		adapter->rx_buff_pool[1].size +
-		adapter->rx_buff_pool[2].size + 1;
+	for(i = 0; i<IbmVethNumBufferPools; i++)
+		rxq_entries += adapter->rx_buff_pool[i].size;
     
 	adapter->buffer_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
 	adapter->filter_list_addr = (void*) get_zeroed_page(GFP_KERNEL);
@@ -502,14 +519,8 @@ static int ibmveth_open(struct net_devic
 	adapter->rx_queue.num_slots = rxq_entries;
 	adapter->rx_queue.toggle = 1;
 
-	if(ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[0]) ||
-	   ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[1]) ||
-	   ibmveth_alloc_buffer_pool(&adapter->rx_buff_pool[2]))
-	{
-		ibmveth_error_printk("unable to allocate buffer pools\n");
-		ibmveth_cleanup(adapter);
-		return -ENOMEM;
-	}
+	/* call change_mtu to init the buffer pools based in initial mtu */
+	ibmveth_change_mtu(netdev, netdev->mtu);
 
 	memcpy(&mac_address, netdev->dev_addr, netdev->addr_len);
 	mac_address = mac_address >> 16;
@@ -885,17 +896,52 @@ static void ibmveth_set_multicast_list(s
 
 static int ibmveth_change_mtu(struct net_device *dev, int new_mtu)
 {
-	if ((new_mtu < 68) || (new_mtu > (1<<20)))
+	struct ibmveth_adapter *adapter = dev->priv;
+	int i;
+	int prev_smaller = 1;
+
+	if ((new_mtu < 68) || 
+	    (new_mtu > (pool_size[IbmVethNumBufferPools-1]) - IBMVETH_BUFF_OH))
 		return -EINVAL;
+
+	for(i = 0; i<IbmVethNumBufferPools; i++) {
+		int activate = 0;
+		if (new_mtu > (pool_size[i]  - IBMVETH_BUFF_OH)) { 
+			activate = 1;
+			prev_smaller= 1;
+		} else {
+			if (prev_smaller)
+				activate = 1;
+			prev_smaller= 0;
+		}
+
+		if (activate && !adapter->rx_buff_pool[i].active) {
+			struct ibmveth_buff_pool *pool = 
+						&adapter->rx_buff_pool[i];
+			if(ibmveth_alloc_buffer_pool(pool)) {
+				ibmveth_error_printk("unable to alloc pool\n");
+				return -ENOMEM;
+			}
+			adapter->rx_buff_pool[i].active = 1;
+		} else if (!activate && adapter->rx_buff_pool[i].active) {
+			adapter->rx_buff_pool[i].active = 0;
+			h_free_logical_lan_buffer(adapter->vdev->unit_address,
+					  (u64)pool_size[i]);
+		}
+
+	}
+
+
+	ibmveth_schedule_replenishing(adapter);
 	dev->mtu = new_mtu;
 	return 0;	
 }
 
 static int __devinit ibmveth_probe(struct vio_dev *dev, const struct vio_device_id *id)
 {
-	int rc;
+	int rc, i;
 	struct net_device *netdev;
-	struct ibmveth_adapter *adapter;
+	struct ibmveth_adapter *adapter = NULL;
 
 	unsigned char *mac_addr_p;
 	unsigned int *mcastFilterSize_p;
@@ -965,9 +1011,9 @@ static int __devinit ibmveth_probe(struc
 
 	memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
 
-	ibmveth_init_buffer_pool(&adapter->rx_buff_pool[0], 0, IbmVethPool0DftCnt, IbmVethPool0DftSize);
-	ibmveth_init_buffer_pool(&adapter->rx_buff_pool[1], 1, IbmVethPool1DftCnt, IbmVethPool1DftSize);
-	ibmveth_init_buffer_pool(&adapter->rx_buff_pool[2], 2, IbmVethPool2DftCnt, IbmVethPool2DftSize);
+	for(i = 0; i<IbmVethNumBufferPools; i++)
+		ibmveth_init_buffer_pool(&adapter->rx_buff_pool[i], i, 
+					 pool_count[i], pool_size[i]);
 
 	ibmveth_debug_printk("adapter @ 0x%p\n", adapter);
 
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index 51a470d..a5d27a9 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -49,6 +49,7 @@
 #define H_SEND_LOGICAL_LAN       0x120
 #define H_MULTICAST_CTRL         0x130
 #define H_CHANGE_LOGICAL_LAN_MAC 0x14C
+#define H_FREE_LOGICAL_LAN_BUFFER 0x1D4
 
 /* hcall macros */
 #define h_register_logical_lan(ua, buflst, rxq, fltlst, mac) \
@@ -69,13 +70,15 @@
 #define h_change_logical_lan_mac(ua, mac) \
   plpar_hcall_norets(H_CHANGE_LOGICAL_LAN_MAC, ua, mac)
 
-#define IbmVethNumBufferPools 3
-#define IbmVethPool0DftSize (1024 * 2)
-#define IbmVethPool1DftSize (1024 * 4)
-#define IbmVethPool2DftSize (1024 * 10)
-#define IbmVethPool0DftCnt  256
-#define IbmVethPool1DftCnt  256
-#define IbmVethPool2DftCnt  256
+#define h_free_logical_lan_buffer(ua, bufsize) \
+  plpar_hcall_norets(H_FREE_LOGICAL_LAN_BUFFER, ua, bufsize)
+
+#define IbmVethNumBufferPools 5
+#define IBMVETH_BUFF_OH 22 /* Overhead: 14 ethernet header + 8 opaque handle */
+
+/* pool_size should be sorted */
+static int pool_size[] = { 512, 1024 * 2, 1024 * 16, 1024 * 32, 1024 * 64 };
+static int pool_count[] = { 256, 768, 256, 256, 256 };
 
 #define IBM_VETH_INVALID_MAP ((u16)0xffff)
 
@@ -90,6 +93,7 @@ struct ibmveth_buff_pool {
     u16 *free_map;
     dma_addr_t *dma_addr;
     struct sk_buff **skbuff;
+    int active;
 };
 
 struct ibmveth_rx_q {
---
0.99.8.GIT


--- NEW FILE 1043-ibmveth-fix-buffer-replenishing.txt ---
Subject: [PATCH] ibmveth fix buffer replenishing
From: Santiago Leon <santil at us.ibm.com>
Date: 1130345228 -0600

This patch removes the allocation of RX skb's  buffers from a workqueue
to be called directly at RX processing time.  This change was suggested
by Dave Miller when the driver was starving the RX buffers and
deadlocking under heavy traffic:

> Allocating RX SKBs via tasklet is, IMHO, the worst way to
> do it.  It is no surprise that there are starvation cases.
>
> If tasklets or work queues get delayed in any way, you lose,
> and it's very easy for a card to catch up with the driver RX'ing
> packets very fast, no matter how aggressive you make the
> replenishing.  By the time you detect that you need to be
> "more aggressive" it is already too late.
> The only pseudo-reliable way is to allocate at RX processing time.
>

Signed-off-by: Santiago Leon <santil at us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/ibmveth.c |   48 ++++++++----------------------------------------
 drivers/net/ibmveth.h |    4 ----
 2 files changed, 8 insertions(+), 44 deletions(-)

applies-to: dd7767a40490d2d532cda4d35a18f8b8e614ab19
e2adbcb480992de8a01acf9218e8bbd9b507fc6f
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index d985b80..aea1598 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -96,7 +96,6 @@ static void ibmveth_proc_unregister_driv
 static void ibmveth_proc_register_adapter(struct ibmveth_adapter *adapter);
 static void ibmveth_proc_unregister_adapter(struct ibmveth_adapter *adapter);
 static irqreturn_t ibmveth_interrupt(int irq, void *dev_instance, struct pt_regs *regs);
-static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter*);
 static inline void ibmveth_rxq_harvest_buffer(struct ibmveth_adapter *adapter);
 
 #ifdef CONFIG_PROC_FS
@@ -257,29 +256,7 @@ static void ibmveth_replenish_buffer_poo
 	atomic_add(buffers_added, &(pool->available));
 }
 
-/* check if replenishing is needed.  */
-static inline int ibmveth_is_replenishing_needed(struct ibmveth_adapter *adapter)
-{
-	int i;
-
-	for(i = 0; i < IbmVethNumBufferPools; i++)
-		if(adapter->rx_buff_pool[i].active &&
-		  (atomic_read(&adapter->rx_buff_pool[i].available) <
-		   adapter->rx_buff_pool[i].threshold))
-			return 1;
-	return 0;
-}
-
-/* kick the replenish tasklet if we need replenishing and it isn't already running */
-static inline void ibmveth_schedule_replenishing(struct ibmveth_adapter *adapter)
-{
-	if(ibmveth_is_replenishing_needed(adapter) &&
-	   (atomic_dec_if_positive(&adapter->not_replenishing) == 0)) {
-		schedule_work(&adapter->replenish_task);
-	}
-}
-
-/* replenish tasklet routine */
+/* replenish routine */
 static void ibmveth_replenish_task(struct ibmveth_adapter *adapter) 
 {
 	int i;
@@ -292,10 +269,6 @@ static void ibmveth_replenish_task(struc
 						     &adapter->rx_buff_pool[i]);
 
 	adapter->rx_no_buffer = *(u64*)(((char*)adapter->buffer_list_addr) + 4096 - 8);
-
-	atomic_inc(&adapter->not_replenishing);
-
-	ibmveth_schedule_replenishing(adapter);
 }
 
 /* empty and free ana buffer pool - also used to do cleanup in error paths */
@@ -563,10 +536,10 @@ static int ibmveth_open(struct net_devic
 		return rc;
 	}
 
-	netif_start_queue(netdev);
+	ibmveth_debug_printk("initial replenish cycle\n");
+	ibmveth_replenish_task(adapter);
 
-	ibmveth_debug_printk("scheduling initial replenish cycle\n");
-	ibmveth_schedule_replenishing(adapter);
+	netif_start_queue(netdev);
 
 	ibmveth_debug_printk("open complete\n");
 
@@ -584,9 +557,6 @@ static int ibmveth_close(struct net_devi
 
 	free_irq(netdev->irq, netdev);
 
-	cancel_delayed_work(&adapter->replenish_task);
-	flush_scheduled_work();
-
 	do {
 		lpar_rc = h_free_logical_lan(adapter->vdev->unit_address);
 	} while (H_isLongBusy(lpar_rc) || (lpar_rc == H_Busy));
@@ -795,7 +765,7 @@ static int ibmveth_poll(struct net_devic
 		}
 	} while(more_work && (frames_processed < max_frames_to_process));
 
-	ibmveth_schedule_replenishing(adapter);
+	ibmveth_replenish_task(adapter);
 
 	if(more_work) {
 		/* more work to do - return that we are not done yet */
@@ -931,8 +901,10 @@ static int ibmveth_change_mtu(struct net
 
 	}
 
+	/* kick the interrupt handler so that the new buffer pools get
+	   replenished or deallocated */
+	ibmveth_interrupt(dev->irq, dev, NULL);
 
-	ibmveth_schedule_replenishing(adapter);
 	dev->mtu = new_mtu;
 	return 0;	
 }
@@ -1017,14 +989,10 @@ static int __devinit ibmveth_probe(struc
 
 	ibmveth_debug_printk("adapter @ 0x%p\n", adapter);
 
-	INIT_WORK(&adapter->replenish_task, (void*)ibmveth_replenish_task, (void*)adapter);
-
 	adapter->buffer_list_dma = DMA_ERROR_CODE;
 	adapter->filter_list_dma = DMA_ERROR_CODE;
 	adapter->rx_queue.queue_dma = DMA_ERROR_CODE;
 
-	atomic_set(&adapter->not_replenishing, 1);
-
 	ibmveth_debug_printk("registering netdev...\n");
 
 	rc = register_netdev(netdev);
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index a5d27a9..a3ea029 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -118,10 +118,6 @@ struct ibmveth_adapter {
     dma_addr_t filter_list_dma;
     struct ibmveth_buff_pool rx_buff_pool[IbmVethNumBufferPools];
     struct ibmveth_rx_q rx_queue;
-    atomic_t not_replenishing;
-
-    /* helper tasks */
-    struct work_struct replenish_task;
 
     /* adapter specific stats */
     u64 replenish_task_cycles;
---
0.99.8.GIT


--- NEW FILE 1044-ibmveth-lockless-TX.txt ---
Subject: [PATCH] ibmveth lockless TX
From: Santiago Leon <santil at us.ibm.com>
Date: 1130345236 -0600

This patch adds the lockless TX feature to the ibmveth driver.  The
hypervisor has its own locking so the only change that is necessary is
to protect the statistics counters.

Signed-off-by: Santiago Leon <santil at us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/ibmveth.c |   44 +++++++++++++++++++++++++++++---------------
 drivers/net/ibmveth.h |    1 +
 2 files changed, 30 insertions(+), 15 deletions(-)

applies-to: 92465e753d0221c0c54862994735a7fe078200fa
60296d9e4be1cd9e096f7804ce6e839e0cbd97cf
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index aea1598..987bcba 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -621,12 +621,18 @@ static int ibmveth_start_xmit(struct sk_
 	unsigned long lpar_rc;
 	int nfrags = 0, curfrag;
 	unsigned long correlator;
+	unsigned long flags;
 	unsigned int retry_count;
+	unsigned int tx_dropped = 0;
+	unsigned int tx_bytes = 0;
+	unsigned int tx_packets = 0;
+	unsigned int tx_send_failed = 0;
+	unsigned int tx_map_failed = 0;
+
 
 	if ((skb_shinfo(skb)->nr_frags + 1) > IbmVethMaxSendFrags) {
-		adapter->stats.tx_dropped++;
-		dev_kfree_skb(skb);
-		return 0;
+		tx_dropped++;
+		goto out;
 	}
 
 	memset(&desc, 0, sizeof(desc));
@@ -645,10 +651,9 @@ static int ibmveth_start_xmit(struct sk_
 
 	if(dma_mapping_error(desc[0].fields.address)) {
 		ibmveth_error_printk("tx: unable to map initial fragment\n");
-		adapter->tx_map_failed++;
-		adapter->stats.tx_dropped++;
-		dev_kfree_skb(skb);
-		return 0;
+		tx_map_failed++;
+		tx_dropped++;
+		goto out;
 	}
 
 	curfrag = nfrags;
@@ -665,8 +670,8 @@ static int ibmveth_start_xmit(struct sk_
 
 		if(dma_mapping_error(desc[curfrag+1].fields.address)) {
 			ibmveth_error_printk("tx: unable to map fragment %d\n", curfrag);
-			adapter->tx_map_failed++;
-			adapter->stats.tx_dropped++;
+			tx_map_failed++;
+			tx_dropped++;
 			/* Free all the mappings we just created */
 			while(curfrag < nfrags) {
 				dma_unmap_single(&adapter->vdev->dev,
@@ -675,8 +680,7 @@ static int ibmveth_start_xmit(struct sk_
 						 DMA_TO_DEVICE);
 				curfrag++;
 			}
-			dev_kfree_skb(skb);
-			return 0;
+			goto out;
 		}
 	}
 
@@ -701,11 +705,11 @@ static int ibmveth_start_xmit(struct sk_
 			ibmveth_error_printk("tx: desc[%i] valid=%d, len=%d, address=0x%d\n", i,
 					     desc[i].fields.valid, desc[i].fields.length, desc[i].fields.address);
 		}
-		adapter->tx_send_failed++;
-		adapter->stats.tx_dropped++;
+		tx_send_failed++;
+		tx_dropped++;
 	} else {
-		adapter->stats.tx_packets++;
-		adapter->stats.tx_bytes += skb->len;
+		tx_packets++;
+		tx_bytes += skb->len;
 		netdev->trans_start = jiffies;
 	}
 
@@ -715,6 +719,14 @@ static int ibmveth_start_xmit(struct sk_
 				desc[nfrags].fields.length, DMA_TO_DEVICE);
 	} while(--nfrags >= 0);
 
+out:	spin_lock_irqsave(&adapter->stats_lock, flags);
+	adapter->stats.tx_dropped += tx_dropped;
+	adapter->stats.tx_bytes += tx_bytes;
+	adapter->stats.tx_packets += tx_packets;
+	adapter->tx_send_failed += tx_send_failed;
+	adapter->tx_map_failed += tx_map_failed;
+	spin_unlock_irqrestore(&adapter->stats_lock, flags);
+
 	dev_kfree_skb(skb);
 	return 0;
 }
@@ -980,6 +992,8 @@ static int __devinit ibmveth_probe(struc
 	netdev->ethtool_ops           = &netdev_ethtool_ops;
 	netdev->change_mtu         = ibmveth_change_mtu;
 	SET_NETDEV_DEV(netdev, &dev->dev);
+ 	netdev->features |= NETIF_F_LLTX; 
+	spin_lock_init(&adapter->stats_lock);
 
 	memcpy(&netdev->dev_addr, &adapter->mac_addr, netdev->addr_len);
 
diff --git a/drivers/net/ibmveth.h b/drivers/net/ibmveth.h
index a3ea029..46919a8 100644
--- a/drivers/net/ibmveth.h
+++ b/drivers/net/ibmveth.h
@@ -131,6 +131,7 @@ struct ibmveth_adapter {
     u64 tx_linearize_failed;
     u64 tx_map_failed;
     u64 tx_send_failed;
+    spinlock_t stats_lock;
 };
 
 struct ibmveth_buf_desc_fields {	
---
0.99.8.GIT


--- NEW FILE 1045-ibmveth-fix-failed-addbuf.txt ---
Subject: [PATCH] ibmveth fix failed addbuf
From: Santiago Leon <santil at us.ibm.com>
Date: 1130345243 -0600

This patch fixes a bug that happens when the hypervisor can't add a
buffer.  The old code wrote IBM_VETH_INVALID_MAP into the free_map
array, so next time the index was used, a ibmveth_assert() caught it and
called BUG().  The patch writes the right value into the free_map array
so that the index can be reused.

Signed-off-by: Santiago Leon <santil at us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/ibmveth.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 40372d93b1c99a0e488adedbbd8c843c26807058
82702d37a559cf94fe238cd3f8ef63cf7fa699a9
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index 987bcba..f581952 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -237,7 +237,7 @@ static void ibmveth_replenish_buffer_poo
 		lpar_rc = h_add_logical_lan_buffer(adapter->vdev->unit_address, desc.desc);
 		    
 		if(lpar_rc != H_Success) {
-			pool->free_map[free_index] = IBM_VETH_INVALID_MAP;
+			pool->free_map[free_index] = index;
 			pool->skbuff[index] = NULL;
 			pool->consumer_index--;
 			dma_unmap_single(&adapter->vdev->dev,
---
0.99.8.GIT


--- NEW FILE 1046-pcnet_cs-fix-mii-init-code-for-older-DL10019-based-cards.txt ---
Subject: [PATCH] pcnet_cs: fix mii init code for older DL10019 based cards
From: Komuro <komurojun-mbn at nifty.com>
Date: 1130530194 -0400

Some older DL10019 based cards need to setup
the auto-negotiation-advertisement register
to advertise 100Full,100Half,10Full and 10Half.

Signed-off-by: <komurojun-mbn at nifty.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/pcmcia/pcnet_cs.c |    6 ++++++
 1 files changed, 6 insertions(+), 0 deletions(-)

applies-to: 695a5b7dca7e2c25aa148fc4bb968857f7bc72c6
d89a64bedf956ef0b406018a7cb76e027fe3e751
diff --git a/drivers/net/pcmcia/pcnet_cs.c b/drivers/net/pcmcia/pcnet_cs.c
index 9f22d13..818c185 100644
--- a/drivers/net/pcmcia/pcnet_cs.c
+++ b/drivers/net/pcmcia/pcnet_cs.c
@@ -1020,6 +1020,12 @@ static void set_misc_reg(struct net_devi
 	} else {
 	    outb(full_duplex ? 4 : 0, nic_base + DLINK_DIAG);
 	}
+    } else if (info->flags & IS_DL10019) {
+	/* Advertise 100F, 100H, 10F, 10H */
+	mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 4, 0x01e1);
+	/* Restart MII autonegotiation */
+	mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x0000);
+	mdio_write(nic_base + DLINK_GPIO, info->eth_phy, 0, 0x1200);
     }
 }
 
---
0.99.8.GIT


--- NEW FILE 1048-s2io-kconfig-help-fix.txt ---
Subject: [PATCH] s2io: kconfig help fix
From: Akinobu Mita <mita at miraclelinux.com>
Date: 1129889202 +0900

The documentation about s2io is available at
Documentation/networking/s2io.txt.

Signed-off-by: Akinobu Mita <mita at miraclelinux.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/Kconfig |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

applies-to: f4013eacc57d2395ceda2f2c46823845dc7cf3c2
9eb343aeb3e106c1e4c07e2863f45b2c121b3b78
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 5148d47..8fa0e26 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2201,8 +2201,8 @@ config S2IO
 	depends on PCI
 	---help---
 	  This driver supports the 10Gbe XFrame NIC of S2IO. 
-	  For help regarding driver compilation, installation and 
-	  tuning please look into ~/drivers/net/s2io/README.txt.
+	  More specific information on configuring the driver is in 
+	  <file:Documentation/networking/s2io.txt>.
 
 config S2IO_NAPI
 	bool "Use Rx Polling (NAPI) (EXPERIMENTAL)"
---
0.99.8.GIT


--- NEW FILE 1049-b44-reports-wrong-advertised-flags.txt ---
Subject: [PATCH] b44 reports wrong advertised flags
From: Matthew Wilcox <matthew at wil.cx>
Date: 1128446717 -0600

Looks like someone used the MII constants instead of the ethtool constants.

Signed-off-by: Matthew Wilcox <matthew at wil.cx>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

applies-to: 5a9d388f4007d21d51ffc83dc3fbf217ffce5ca4
adf6e00064ebcd3d82009ba6ef66f489f0885ebd
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 282ebd1..225d14f 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1619,14 +1619,14 @@ static int b44_get_settings(struct net_d
 
 	cmd->advertising = 0;
 	if (bp->flags & B44_FLAG_ADV_10HALF)
-		cmd->advertising |= ADVERTISE_10HALF;
+		cmd->advertising |= ADVERTISED_10baseT_Half;
 	if (bp->flags & B44_FLAG_ADV_10FULL)
-		cmd->advertising |= ADVERTISE_10FULL;
+		cmd->advertising |= ADVERTISED_10baseT_Full;
 	if (bp->flags & B44_FLAG_ADV_100HALF)
-		cmd->advertising |= ADVERTISE_100HALF;
+		cmd->advertising |= ADVERTISED_100baseT_Half;
 	if (bp->flags & B44_FLAG_ADV_100FULL)
-		cmd->advertising |= ADVERTISE_100FULL;
-	cmd->advertising |= ADVERTISE_PAUSE_CAP | ADVERTISE_PAUSE_ASYM;
+		cmd->advertising |= ADVERTISED_100baseT_Full;
+	cmd->advertising |= ADVERTISED_Pause | ADVERTISED_Asym_Pause;
 	cmd->speed = (bp->flags & B44_FLAG_100_BASE_T) ?
 		SPEED_100 : SPEED_10;
 	cmd->duplex = (bp->flags & B44_FLAG_FULL_DUPLEX) ?
---
0.99.8.GIT


--- NEW FILE 1050-sis190.c-fix-multicast-MAC-filter.txt ---
Subject: [PATCH] sis190.c: fix multicast MAC filter
From: Aurelien Jarno <aurelien at aurel32.net>
Date: 1128547798 +0200

Here is a patch that changes the way the MAC filter is computed for the
multicast addresses. The computation is taken from the SiS GPL driver.

This patch is necessary to get IPv6 working.

Signed-off-by: Aurelien Jarno <aurelien at aurel32.net>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sis190.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: d28e9462118fe0702fb717838e094867aae00f7b
8fee5f51a56aa7a67d955993572a2ae05d31a2c6
diff --git a/drivers/net/sis190.c b/drivers/net/sis190.c
index 92f7552..478791e 100644
--- a/drivers/net/sis190.c
+++ b/drivers/net/sis190.c
@@ -842,7 +842,7 @@ static void sis190_set_rx_mode(struct ne
 		for (i = 0, mclist = dev->mc_list; mclist && i < dev->mc_count;
 		     i++, mclist = mclist->next) {
 			int bit_nr =
-				ether_crc(ETH_ALEN, mclist->dmi_addr) >> 26;
+				ether_crc(ETH_ALEN, mclist->dmi_addr) & 0x3f;
 			mc_filter[bit_nr >> 5] |= 1 << (bit_nr & 31);
 			rx_mode |= AcceptMulticast;
 		}
---
0.99.8.GIT


--- NEW FILE 1051-smc91x-shut-down-power-after-probing.txt ---
Subject: [PATCH] smc91x: shut down power after probing
From: Nicolas Pitre <nico at cam.org>
Date: 1128525024 -0400

If the interface is not used right away after being probed it wastes
power needlessly. Noted by Holger Schurig.

Signed-off-by: Nicolas Pitre <nico at cam.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/smc91x.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

applies-to: 2160ea3f622aa0b34df484f81c577ba33ca8f830
99e1baf869cf20791e66e38facd51d14b28551f8
diff --git a/drivers/net/smc91x.c b/drivers/net/smc91x.c
index 1438fdd..c5bc8ae 100644
--- a/drivers/net/smc91x.c
+++ b/drivers/net/smc91x.c
@@ -1983,6 +1983,10 @@ static int __init smc_probe(struct net_d
 	if (lp->version >= (CHIP_91100 << 4))
 		smc_phy_detect(dev);
 
+	/* then shut everything down to save power */
+	smc_shutdown(dev);
+	smc_phy_powerdown(dev);
+
 	/* Set default parameters */
 	lp->msg_enable = NETIF_MSG_LINK;
 	lp->ctl_rfduplx = 0;
---
0.99.8.GIT


--- NEW FILE 1053-starfire-free_irq-on-error-path-of-netdev_open.txt ---
Subject: [PATCH] starfire: free_irq() on error path of netdev_open()
From: Alexey Dobriyan <adobriyan at gmail.com>
Date: 1128636323 +0400

Signed-off-by: Alexey Dobriyan <adobriyan at gmail.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/starfire.c |    4 +++-
 1 files changed, 3 insertions(+), 1 deletions(-)

applies-to: 28e37cd6ae4a7c6f6f3e0dcc71bb7a451caf28ad
d8840ac907c7943bc7e196b11812adfa95cb28ef
diff --git a/drivers/net/starfire.c b/drivers/net/starfire.c
index efdb179..38b2b0a 100644
--- a/drivers/net/starfire.c
+++ b/drivers/net/starfire.c
@@ -1091,8 +1091,10 @@ static int netdev_open(struct net_device
 		rx_ring_size = sizeof(struct starfire_rx_desc) * RX_RING_SIZE;
 		np->queue_mem_size = tx_done_q_size + rx_done_q_size + tx_ring_size + rx_ring_size;
 		np->queue_mem = pci_alloc_consistent(np->pci_dev, np->queue_mem_size, &np->queue_mem_dma);
-		if (np->queue_mem == 0)
+		if (np->queue_mem == NULL) {
+			free_irq(dev->irq, dev);
 			return -ENOMEM;
+		}
 
 		np->tx_done_q     = np->queue_mem;
 		np->tx_done_q_dma = np->queue_mem_dma;
---
0.99.8.GIT


--- NEW FILE 1056-netdrvr-b44-include-linux-dma-mapping.h-to-eliminate-warning.txt ---
Subject: [PATCH] [netdrvr b44] include linux/dma-mapping.h to eliminate warning
From: Andrew Morton <akpm at osdl.org>
Date: 1130531882 -0400

---

 drivers/net/b44.c |    1 +
 1 files changed, 1 insertions(+), 0 deletions(-)

applies-to: 7e553a6018862338d80fb5b0e4070a371a8fb001
89358f90ab6f6657d386e77e19c805d7ab88694f
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 225d14f..ab84507 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -19,6 +19,7 @@
 #include <linux/delay.h>
 #include <linux/init.h>
 #include <linux/version.h>
+#include <linux/dma-mapping.h>
 
 #include <asm/uaccess.h>
 #include <asm/io.h>
---
0.99.8.GIT


--- NEW FILE 1057-sundance-fix-DFE-580TX-Tx-Underrun.txt ---
Subject: [PATCH] sundance: fix DFE-580TX Tx Underrun
From: Philippe De Muyter <phdm at macqel.be>
Date: 1130495027 +0200

Under heavy PCI bus load, ports of the DFE-580TX 4-ethernet port board stop
working, with currently no other cure than a powercycle.  Here is a tested
fix.  By the way, I also fixed some references and attribution.

Signed-off-by: Philippe De Muyter <phdm at macqel.be>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sundance.c |   62 +++++++++++++++++++++++++++++++++++++-----------
 1 files changed, 48 insertions(+), 14 deletions(-)

applies-to: 3b0192df7f164e1f409385626e605cf09bd93c93
b71b95efa5abca33e1bfb85d55162c7f99f54c23
diff --git a/drivers/net/sundance.c b/drivers/net/sundance.c
index 5de0554..0ab9c38 100644
--- a/drivers/net/sundance.c
+++ b/drivers/net/sundance.c
@@ -80,7 +80,7 @@
 	  I/O access could affect performance in ARM-based system
 	- Add Linux software VLAN support
 	
-	Version LK1.08 (D-Link):
+	Version LK1.08 (Philippe De Muyter phdm at macqel.be):
 	- Fix bug of custom mac address 
 	(StationAddr register only accept word write) 
 
@@ -91,11 +91,14 @@
 	Version LK1.09a (ICPlus):
 	- Add the delay time in reading the contents of EEPROM
 
+	Version LK1.10 (Philippe De Muyter phdm at macqel.be):
+	- Make 'unblock interface after Tx underrun' work
+
 */
 
 #define DRV_NAME	"sundance"
-#define DRV_VERSION	"1.01+LK1.09a"
-#define DRV_RELDATE	"10-Jul-2003"
+#define DRV_VERSION	"1.01+LK1.10"
+#define DRV_RELDATE	"28-Oct-2005"
 
 
 /* The user-configurable values.
@@ -263,8 +266,10 @@ IV. Notes
 IVb. References
 
 The Sundance ST201 datasheet, preliminary version.
-http://cesdis.gsfc.nasa.gov/linux/misc/100mbps.html
-http://cesdis.gsfc.nasa.gov/linux/misc/NWay.html
+The Kendin KS8723 datasheet, preliminary version.
+The ICplus IP100 datasheet, preliminary version.
+http://www.scyld.com/expert/100mbps.html
+http://www.scyld.com/expert/NWay.html
 
 IVc. Errata
 
@@ -500,6 +505,25 @@ static int netdev_ioctl(struct net_devic
 static int  netdev_close(struct net_device *dev);
 static struct ethtool_ops ethtool_ops;
 
+static void sundance_reset(struct net_device *dev, unsigned long reset_cmd)
+{
+	struct netdev_private *np = netdev_priv(dev);
+	void __iomem *ioaddr = np->base + ASICCtrl;
+	int countdown;
+
+	/* ST201 documentation states ASICCtrl is a 32bit register */
+	iowrite32 (reset_cmd | ioread32 (ioaddr), ioaddr);
+	/* ST201 documentation states reset can take up to 1 ms */
+	countdown = 10 + 1;
+	while (ioread32 (ioaddr) & (ResetBusy << 16)) {
+		if (--countdown == 0) {
+			printk(KERN_WARNING "%s : reset not completed !!\n", dev->name);
+			break;
+		}
+		udelay(100);
+	}
+}
+
 static int __devinit sundance_probe1 (struct pci_dev *pdev,
 				      const struct pci_device_id *ent)
 {
@@ -1190,23 +1214,33 @@ static irqreturn_t intr_handler(int irq,
 					    ("%s: Transmit status is %2.2x.\n",
 				     	dev->name, tx_status);
 				if (tx_status & 0x1e) {
+					if (netif_msg_tx_err(np))
+						printk("%s: Transmit error status %4.4x.\n",
+							   dev->name, tx_status);
 					np->stats.tx_errors++;
 					if (tx_status & 0x10)
 						np->stats.tx_fifo_errors++;
 					if (tx_status & 0x08)
 						np->stats.collisions++;
+					if (tx_status & 0x04)
+						np->stats.tx_fifo_errors++;
 					if (tx_status & 0x02)
 						np->stats.tx_window_errors++;
-					/* This reset has not been verified!. */
-					if (tx_status & 0x10) {	/* Reset the Tx. */
-						np->stats.tx_fifo_errors++;
-						spin_lock(&np->lock);
-						reset_tx(dev);
-						spin_unlock(&np->lock);
+					/*
+					** This reset has been verified on
+					** DFE-580TX boards ! phdm at macqel.be.
+					*/
+					if (tx_status & 0x10) {	/* TxUnderrun */
+						unsigned short txthreshold;
+
+						txthreshold = ioread16 (ioaddr + TxStartThresh);
+						/* Restart Tx FIFO and transmitter */
+						sundance_reset(dev, (NetworkReset|FIFOReset|TxReset) << 16);
+						iowrite16 (txthreshold, ioaddr + TxStartThresh);
+						/* No need to reset the Tx pointer here */
 					}
-					if (tx_status & 0x1e)	/* Restart the Tx. */
-						iowrite16 (TxEnable,
-							ioaddr + MACCtrl1);
+					/* Restart the Tx. */
+					iowrite16 (TxEnable, ioaddr + MACCtrl1);
 				}
 				/* Yup, this is a documentation bug.  It cost me *hours*. */
 				iowrite16 (0, ioaddr + TxStatus);
---
0.99.8.GIT


--- NEW FILE 1061-sis900-come-alive-after-temporary-memory-shortage.txt ---
Subject: [PATCH] sis900: come alive after temporary memory shortage
From: Vasily Averin <vvs at sw.ru>
Date: 1130532395 -0400

1) Forgotten counter incrementation in sis900_rx() in case
     it doesn't get memory for skb, that leads to whole interface failure.
     Problem is accompanied with messages:
    eth0: Memory squeeze,deferring packet.
    eth0: NULL pointer encountered in Rx ring, skipping

2) If counter cur_rx overflows and there'll be temporary memory problems
     buffer can't be recreated later, when memory IS available.

3) Limit the work in handler to prevent the endless packets processing
   if new packets are generated faster then handled.

Signed-off-by: Konstantin Khorenko <khorenko at sw.ru>
Signed-off-by: Vasily Averin <vvs at sw.ru>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/sis900.c |   16 ++++++++++++----
 1 files changed, 12 insertions(+), 4 deletions(-)

applies-to: f17920db9780a8b3feed97fdf4eb5704243e25e9
7380a78a973a8109c13cb0e47617c456b6f6e1f5
diff --git a/drivers/net/sis900.c b/drivers/net/sis900.c
index 23b713c..1d4d886 100644
--- a/drivers/net/sis900.c
+++ b/drivers/net/sis900.c
@@ -1696,15 +1696,20 @@ static int sis900_rx(struct net_device *
 	long ioaddr = net_dev->base_addr;
 	unsigned int entry = sis_priv->cur_rx % NUM_RX_DESC;
 	u32 rx_status = sis_priv->rx_ring[entry].cmdsts;
+	int rx_work_limit;
 
 	if (netif_msg_rx_status(sis_priv))
 		printk(KERN_DEBUG "sis900_rx, cur_rx:%4.4d, dirty_rx:%4.4d "
 		       "status:0x%8.8x\n",
 		       sis_priv->cur_rx, sis_priv->dirty_rx, rx_status);
+	rx_work_limit = sis_priv->dirty_rx + NUM_RX_DESC - sis_priv->cur_rx;
 
 	while (rx_status & OWN) {
 		unsigned int rx_size;
 
+		if (--rx_work_limit < 0)
+			break;
+
 		rx_size = (rx_status & DSIZE) - CRC_SIZE;
 
 		if (rx_status & (ABORT|OVERRUN|TOOLONG|RUNT|RXISERR|CRCERR|FAERR)) {
@@ -1732,9 +1737,11 @@ static int sis900_rx(struct net_device *
 			   we are working on NULL sk_buff :-( */
 			if (sis_priv->rx_skbuff[entry] == NULL) {
 				if (netif_msg_rx_err(sis_priv))
-					printk(KERN_INFO "%s: NULL pointer " 
-						"encountered in Rx ring, skipping\n",
-						net_dev->name);
+					printk(KERN_WARNING "%s: NULL pointer " 
+					      "encountered in Rx ring\n"
+					      "cur_rx:%4.4d, dirty_rx:%4.4d\n",
+					      net_dev->name, sis_priv->cur_rx,
+					      sis_priv->dirty_rx);
 				break;
 			}
 
@@ -1770,6 +1777,7 @@ static int sis900_rx(struct net_device *
 				sis_priv->rx_ring[entry].cmdsts = 0;
 				sis_priv->rx_ring[entry].bufptr = 0;
 				sis_priv->stats.rx_dropped++;
+				sis_priv->cur_rx++;
 				break;
 			}
 			skb->dev = net_dev;
@@ -1787,7 +1795,7 @@ static int sis900_rx(struct net_device *
 
 	/* refill the Rx buffer, what if the rate of refilling is slower
 	 * than consuming ?? */
-	for (;sis_priv->cur_rx - sis_priv->dirty_rx > 0; sis_priv->dirty_rx++) {
+	for (; sis_priv->cur_rx != sis_priv->dirty_rx; sis_priv->dirty_rx++) {
 		struct sk_buff *skb;
 
 		entry = sis_priv->dirty_rx % NUM_RX_DESC;
---
0.99.8.GIT


--- NEW FILE 1062-drivers-net-Remove-pointless-checks-for-NULL-prior-to-calling-kfree.txt ---
Subject: [PATCH] drivers/net: Remove pointless checks for NULL prior to calling kfree()
From: Jesper Juhl <jesper.juhl at gmail.com>
Date: 1130532793 -0400

---

 drivers/net/acenic.c                       |    6 +---
 drivers/net/au1000_eth.c                   |    6 +---
 drivers/net/b44.c                          |   12 ++-----
 drivers/net/bmac.c                         |    6 +---
 drivers/net/bnx2.c                         |   12 ++-----
 drivers/net/e1000/e1000_ethtool.c          |    7 +---
 drivers/net/hamradio/mkiss.c               |    6 +---
 drivers/net/ibmveth.c                      |    6 +---
 drivers/net/irda/donauboe.c                |    6 +---
 drivers/net/irda/irda-usb.c                |    6 +---
 drivers/net/irda/irport.c                  |    3 +-
 drivers/net/irda/sir_dev.c                 |    3 +-
 drivers/net/irda/vlsi_ir.c                 |    3 +-
 drivers/net/mace.c                         |    6 +---
 drivers/net/ni65.c                         |    9 ++---
 drivers/net/rrunner.c                      |    6 +---
 drivers/net/s2io.c                         |    3 +-
 drivers/net/saa9730.c                      |    8 +----
 drivers/net/tg3.c                          |    6 +---
 drivers/net/tulip/de2104x.c                |    6 +---
 drivers/net/tulip/tulip_core.c             |    6 +---
 drivers/net/via-velocity.c                 |    6 +---
 drivers/net/wireless/airo.c                |   48 +++++++++++-----------------
 drivers/net/wireless/airo_cs.c             |    4 +-
 drivers/net/wireless/atmel.c               |    6 +---
 drivers/net/wireless/atmel_cs.c            |    3 +-
 drivers/net/wireless/hostap/hostap_ioctl.c |    9 +----
 drivers/net/wireless/prism54/islpci_dev.c  |    3 +-
 drivers/net/wireless/prism54/oid_mgt.c     |    9 ++---
 drivers/net/wireless/strip.c               |   38 ++++++++--------------
 include/net/ax25.h                         |    3 +-
 include/net/netrom.h                       |    3 +-
 32 files changed, 90 insertions(+), 174 deletions(-)

applies-to: fb64f857892546a441b27af54921e1669aa30610
b4558ea93d66a43f7990d26f145fd4c54a01c9bf
diff --git a/drivers/net/acenic.c b/drivers/net/acenic.c
index dbecc6b..b8953de 100644
--- a/drivers/net/acenic.c
+++ b/drivers/net/acenic.c
@@ -871,10 +871,8 @@ static void ace_init_cleanup(struct net_
 	if (ap->info)
 		pci_free_consistent(ap->pdev, sizeof(struct ace_info),
 				    ap->info, ap->info_dma);
-	if (ap->skb)
-		kfree(ap->skb);
-	if (ap->trace_buf)
-		kfree(ap->trace_buf);
+	kfree(ap->skb);
+	kfree(ap->trace_buf);
 
 	if (dev->irq)
 		free_irq(dev->irq, dev);
diff --git a/drivers/net/au1000_eth.c b/drivers/net/au1000_eth.c
index 7850691..332e995 100644
--- a/drivers/net/au1000_eth.c
+++ b/drivers/net/au1000_eth.c
@@ -1606,8 +1606,7 @@ err_out:
 	/* here we should have a valid dev plus aup-> register addresses
 	 * so we can reset the mac properly.*/
 	reset_mac(dev);
-	if (aup->mii)
-		kfree(aup->mii);
+	kfree(aup->mii);
 	for (i = 0; i < NUM_RX_DMA; i++) {
 		if (aup->rx_db_inuse[i])
 			ReleaseDB(aup, aup->rx_db_inuse[i]);
@@ -1806,8 +1805,7 @@ static void __exit au1000_cleanup_module
 		if (dev) {
 			aup = (struct au1000_private *) dev->priv;
 			unregister_netdev(dev);
-			if (aup->mii)
-				kfree(aup->mii);
+			kfree(aup->mii);
 			for (j = 0; j < NUM_RX_DMA; j++) {
 				if (aup->rx_db_inuse[j])
 					ReleaseDB(aup, aup->rx_db_inuse[j]);
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index ab84507..5485e3b 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1131,14 +1131,10 @@ static void b44_init_rings(struct b44 *b
  */
 static void b44_free_consistent(struct b44 *bp)
 {
-	if (bp->rx_buffers) {
-		kfree(bp->rx_buffers);
-		bp->rx_buffers = NULL;
-	}
-	if (bp->tx_buffers) {
-		kfree(bp->tx_buffers);
-		bp->tx_buffers = NULL;
-	}
+	kfree(bp->rx_buffers);
+	bp->rx_buffers = NULL;
+	kfree(bp->tx_buffers);
+	bp->tx_buffers = NULL;
 	if (bp->rx_ring) {
 		if (bp->flags & B44_FLAG_RX_RING_HACK) {
 			dma_unmap_single(&bp->pdev->dev, bp->rx_ring_dma,
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 60dba4a..73f2fcf 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1689,10 +1689,8 @@ static void __exit bmac_exit(void)
 {
 	macio_unregister_driver(&bmac_driver);
 
-	if (bmac_emergency_rxbuf != NULL) {
-		kfree(bmac_emergency_rxbuf);
-		bmac_emergency_rxbuf = NULL;
-	}
+	kfree(bmac_emergency_rxbuf);
+	bmac_emergency_rxbuf = NULL;
 }
 
 MODULE_AUTHOR("Randy Gobbel/Paul Mackerras");
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 3a2ace0..11d2523 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -314,20 +314,16 @@ bnx2_free_mem(struct bnx2 *bp)
 				    bp->tx_desc_ring, bp->tx_desc_mapping);
 		bp->tx_desc_ring = NULL;
 	}
-	if (bp->tx_buf_ring) {
-		kfree(bp->tx_buf_ring);
-		bp->tx_buf_ring = NULL;
-	}
+	kfree(bp->tx_buf_ring);
+	bp->tx_buf_ring = NULL;
 	if (bp->rx_desc_ring) {
 		pci_free_consistent(bp->pdev,
 				    sizeof(struct rx_bd) * RX_DESC_CNT,
 				    bp->rx_desc_ring, bp->rx_desc_mapping);
 		bp->rx_desc_ring = NULL;
 	}
-	if (bp->rx_buf_ring) {
-		kfree(bp->rx_buf_ring);
-		bp->rx_buf_ring = NULL;
-	}
+	kfree(bp->rx_buf_ring);
+	bp->rx_buf_ring = NULL;
 }
 
 static int
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 6b9acc7..9c7feae 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -965,11 +965,8 @@ e1000_free_desc_rings(struct e1000_adapt
 	if(rxdr->desc)
 		pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma);
 
-	if(txdr->buffer_info)
-		kfree(txdr->buffer_info);
-	if(rxdr->buffer_info)
-		kfree(rxdr->buffer_info);
-
+	kfree(txdr->buffer_info);
+	kfree(rxdr->buffer_info);
 	return;
 }
 
diff --git a/drivers/net/hamradio/mkiss.c b/drivers/net/hamradio/mkiss.c
index 85d6dc0..3e9accf 100644
--- a/drivers/net/hamradio/mkiss.c
+++ b/drivers/net/hamradio/mkiss.c
@@ -390,10 +390,8 @@ static void ax_changedmtu(struct mkiss *
 		       "MTU change cancelled.\n",
 		       ax->dev->name);
 		dev->mtu = ax->mtu;
-		if (xbuff != NULL)
-			kfree(xbuff);
-		if (rbuff != NULL)
-			kfree(rbuff);
+		kfree(xbuff);
+		kfree(rbuff);
 		return;
 	}
 
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index f581952..36da54a 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -276,10 +276,8 @@ static void ibmveth_free_buffer_pool(str
 {
 	int i;
 
-	if(pool->free_map) {
-		kfree(pool->free_map);
-		pool->free_map  = NULL;
-	}
+	kfree(pool->free_map);
+	pool->free_map = NULL;
 
 	if(pool->skbuff && pool->dma_addr) {
 		for(i = 0; i < pool->size; ++i) {
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 0a08c53..0282771 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1695,11 +1695,9 @@ toshoboe_open (struct pci_dev *pci_dev, 
 
 freebufs:
   for (i = 0; i < TX_SLOTS; ++i)
-    if (self->tx_bufs[i])
-      kfree (self->tx_bufs[i]);
+    kfree (self->tx_bufs[i]);
   for (i = 0; i < RX_SLOTS; ++i)
-    if (self->rx_bufs[i])
-      kfree (self->rx_bufs[i]);
+    kfree (self->rx_bufs[i]);
   kfree(self->ringbuf);
 
 freeregion:
diff --git a/drivers/net/irda/irda-usb.c b/drivers/net/irda/irda-usb.c
index 6c766fd..c22c051 100644
--- a/drivers/net/irda/irda-usb.c
+++ b/drivers/net/irda/irda-usb.c
@@ -1168,10 +1168,8 @@ static inline void irda_usb_close(struct
 	unregister_netdev(self->netdev);
 
 	/* Remove the speed buffer */
-	if (self->speed_buff != NULL) {
-		kfree(self->speed_buff);
-		self->speed_buff = NULL;
-	}
+	kfree(self->speed_buff);
+	self->speed_buff = NULL;
 }
 
 /********************** USB CONFIG SUBROUTINES **********************/
diff --git a/drivers/net/irda/irport.c b/drivers/net/irda/irport.c
index 5971315..3d016a4 100644
--- a/drivers/net/irda/irport.c
+++ b/drivers/net/irda/irport.c
@@ -235,8 +235,7 @@ static int irport_close(struct irport_cb
 		   __FUNCTION__, self->io.sir_base);
 	release_region(self->io.sir_base, self->io.sir_ext);
 
-	if (self->tx_buff.head)
-		kfree(self->tx_buff.head);
+	kfree(self->tx_buff.head);
 	
 	if (self->rx_buff.skb)
 		kfree_skb(self->rx_buff.skb);
diff --git a/drivers/net/irda/sir_dev.c b/drivers/net/irda/sir_dev.c
index efc5a88..df22b8b 100644
--- a/drivers/net/irda/sir_dev.c
+++ b/drivers/net/irda/sir_dev.c
@@ -490,8 +490,7 @@ static void sirdev_free_buffers(struct s
 {
 	if (dev->rx_buff.skb)
 		kfree_skb(dev->rx_buff.skb);
-	if (dev->tx_buff.head)
-		kfree(dev->tx_buff.head);
+	kfree(dev->tx_buff.head);
 	dev->rx_buff.head = dev->tx_buff.head = NULL;
 	dev->rx_buff.skb = NULL;
 }
diff --git a/drivers/net/irda/vlsi_ir.c b/drivers/net/irda/vlsi_ir.c
index 651c5a6..a9f49f0 100644
--- a/drivers/net/irda/vlsi_ir.c
+++ b/drivers/net/irda/vlsi_ir.c
@@ -473,8 +473,7 @@ static int vlsi_free_ring(struct vlsi_ri
 		rd_set_addr_status(rd, 0, 0);
 		if (busaddr)
 			pci_unmap_single(r->pdev, busaddr, r->len, r->dir);
-		if (rd->buf)
-			kfree(rd->buf);
+		kfree(rd->buf);
 	}
 	kfree(r);
 	return 0;
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 81d0a26..09b1e7b 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -1035,10 +1035,8 @@ static void __exit mace_cleanup(void)
 {
 	macio_unregister_driver(&mace_driver);
 
-	if (dummy_buf) {
-		kfree(dummy_buf);
-		dummy_buf = NULL;
-	}
+	kfree(dummy_buf);
+	dummy_buf = NULL;
 }
 
 MODULE_AUTHOR("Paul Mackerras");
diff --git a/drivers/net/ni65.c b/drivers/net/ni65.c
index 925d1df..bb42ff2 100644
--- a/drivers/net/ni65.c
+++ b/drivers/net/ni65.c
@@ -696,8 +696,7 @@ static void ni65_free_buffer(struct priv
 		return;
 
 	for(i=0;i<TMDNUM;i++) {
-		if(p->tmdbounce[i])
-			kfree(p->tmdbounce[i]);
+		kfree(p->tmdbounce[i]);
 #ifdef XMT_VIA_SKB
 		if(p->tmd_skb[i])
 			dev_kfree_skb(p->tmd_skb[i]);
@@ -710,12 +709,10 @@ static void ni65_free_buffer(struct priv
 		if(p->recv_skb[i])
 			dev_kfree_skb(p->recv_skb[i]);
 #else
-		if(p->recvbounce[i])
-			kfree(p->recvbounce[i]);
+		kfree(p->recvbounce[i]);
 #endif
 	}
-	if(p->self)
-		kfree(p->self);
+	kfree(p->self);
 }
 
 
diff --git a/drivers/net/rrunner.c b/drivers/net/rrunner.c
index ec1a18d..19c2df9 100644
--- a/drivers/net/rrunner.c
+++ b/drivers/net/rrunner.c
@@ -1710,10 +1710,8 @@ static int rr_ioctl(struct net_device *d
 			error = -EFAULT;
 		}
 	wf_out:
-		if (oldimage)
-			kfree(oldimage);
-		if (image)
-			kfree(image);
+		kfree(oldimage);
+		kfree(image);
 		return error;
 		
 	case SIOCRRID:
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index d303d16..5ea8977 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -705,8 +705,7 @@ static void free_shared_mem(struct s2io_
 			}
 			kfree(mac_control->rings[i].ba[j]);
 		}
-		if (mac_control->rings[i].ba)
-			kfree(mac_control->rings[i].ba);
+		kfree(mac_control->rings[i].ba);
 	}
 #endif
 
diff --git a/drivers/net/saa9730.c b/drivers/net/saa9730.c
index fd01670..110e777 100644
--- a/drivers/net/saa9730.c
+++ b/drivers/net/saa9730.c
@@ -997,10 +997,7 @@ static void __devexit saa9730_remove_one
 
         if (dev) {
                 unregister_netdev(dev);
-
-		if (dev->priv)
-			kfree(dev->priv);
-
+		kfree(dev->priv);
                 free_netdev(dev);
                 pci_release_regions(pdev);
                 pci_disable_device(pdev);
@@ -1096,8 +1093,7 @@ static int lan_saa9730_init(struct net_d
 	return 0;
 
  out:
-	if (dev->priv)
-		kfree(dev->priv);
+	kfree(dev->priv);
 	return ret;
 }
 
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index 551c944..b547233 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -3918,10 +3918,8 @@ static void tg3_init_rings(struct tg3 *t
  */
 static void tg3_free_consistent(struct tg3 *tp)
 {
-	if (tp->rx_std_buffers) {
-		kfree(tp->rx_std_buffers);
-		tp->rx_std_buffers = NULL;
-	}
+	kfree(tp->rx_std_buffers);
+	tp->rx_std_buffers = NULL;
 	if (tp->rx_std) {
 		pci_free_consistent(tp->pdev, TG3_RX_RING_BYTES,
 				    tp->rx_std, tp->rx_std_mapping);
diff --git a/drivers/net/tulip/de2104x.c b/drivers/net/tulip/de2104x.c
index 6b8eee8..d7fb3ff 100644
--- a/drivers/net/tulip/de2104x.c
+++ b/drivers/net/tulip/de2104x.c
@@ -2076,8 +2076,7 @@ static int __init de_init_one (struct pc
 	return 0;
 
 err_out_iomap:
-	if (de->ee_data)
-		kfree(de->ee_data);
+	kfree(de->ee_data);
 	iounmap(regs);
 err_out_res:
 	pci_release_regions(pdev);
@@ -2096,8 +2095,7 @@ static void __exit de_remove_one (struct
 	if (!dev)
 		BUG();
 	unregister_netdev(dev);
-	if (de->ee_data)
-		kfree(de->ee_data);
+	kfree(de->ee_data);
 	iounmap(de->regs);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
diff --git a/drivers/net/tulip/tulip_core.c b/drivers/net/tulip/tulip_core.c
index 6266a9a..125ed00 100644
--- a/drivers/net/tulip/tulip_core.c
+++ b/drivers/net/tulip/tulip_core.c
@@ -1727,8 +1727,7 @@ err_out_free_ring:
 			     tp->rx_ring, tp->rx_ring_dma);
 
 err_out_mtable:
-	if (tp->mtable)
-		kfree (tp->mtable);
+	kfree (tp->mtable);
 	pci_iounmap(pdev, ioaddr);
 
 err_out_free_res:
@@ -1806,8 +1805,7 @@ static void __devexit tulip_remove_one (
 			     sizeof (struct tulip_rx_desc) * RX_RING_SIZE +
 			     sizeof (struct tulip_tx_desc) * TX_RING_SIZE,
 			     tp->rx_ring, tp->rx_ring_dma);
-	if (tp->mtable)
-		kfree (tp->mtable);
+	kfree (tp->mtable);
 	pci_iounmap(pdev, tp->base_addr);
 	free_netdev (dev);
 	pci_release_regions (pdev);
diff --git a/drivers/net/via-velocity.c b/drivers/net/via-velocity.c
index abc5cee..a368d08 100644
--- a/drivers/net/via-velocity.c
+++ b/drivers/net/via-velocity.c
@@ -1212,10 +1212,8 @@ static void velocity_free_td_ring(struct
 			velocity_free_td_ring_entry(vptr, j, i);
 
 		}
-		if (vptr->td_infos[j]) {
-			kfree(vptr->td_infos[j]);
-			vptr->td_infos[j] = NULL;
-		}
+		kfree(vptr->td_infos[j]);
+		vptr->td_infos[j] = NULL;
 	}
 }
 
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index cb429e7..4c11699 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2381,14 +2381,10 @@ void stop_airo_card( struct net_device *
 			dev_kfree_skb(skb);
 	}
 
-	if (ai->flash)
-		kfree(ai->flash);
-	if (ai->rssi)
-		kfree(ai->rssi);
-	if (ai->APList)
-		kfree(ai->APList);
-	if (ai->SSID)
-		kfree(ai->SSID);
+	kfree(ai->flash);
+	kfree(ai->rssi);
+	kfree(ai->APList);
+	kfree(ai->SSID);
 	if (freeres) {
 		/* PCMCIA frees this stuff, so only for PCI and ISA */
 	        release_region( dev->base_addr, 64 );
@@ -3626,10 +3622,8 @@ static u16 setup_card(struct airo_info *
 	int rc;
 
 	memset( &mySsid, 0, sizeof( mySsid ) );
-	if (ai->flash) {
-		kfree (ai->flash);
-		ai->flash = NULL;
-	}
+	kfree (ai->flash);
+	ai->flash = NULL;
 
 	/* The NOP is the first step in getting the card going */
 	cmd.cmd = NOP;
@@ -3666,14 +3660,10 @@ static u16 setup_card(struct airo_info *
 		tdsRssiRid rssi_rid;
 		CapabilityRid cap_rid;
 
-		if (ai->APList) {
-			kfree(ai->APList);
-			ai->APList = NULL;
-		}
-		if (ai->SSID) {
-			kfree(ai->SSID);
-			ai->SSID = NULL;
-		}
+		kfree(ai->APList);
+		ai->APList = NULL;
+		kfree(ai->SSID);
+		ai->SSID = NULL;
 		// general configuration (read/modify/write)
 		status = readConfigRid(ai, lock);
 		if ( status != SUCCESS ) return ERROR;
@@ -3687,10 +3677,8 @@ static u16 setup_card(struct airo_info *
 				memcpy(ai->rssi, (u8*)&rssi_rid + 2, 512); /* Skip RID length member */
 		}
 		else {
-			if (ai->rssi) {
-				kfree(ai->rssi);
-				ai->rssi = NULL;
-			}
+			kfree(ai->rssi);
+			ai->rssi = NULL;
 			if (cap_rid.softCap & 8)
 				ai->config.rmode |= RXMODE_NORMALIZED_RSSI;
 			else
@@ -5369,11 +5357,13 @@ static int proc_BSSList_open( struct ino
 
 static int proc_close( struct inode *inode, struct file *file )
 {
-	struct proc_data *data = (struct proc_data *)file->private_data;
-	if ( data->on_close != NULL ) data->on_close( inode, file );
-	if ( data->rbuffer ) kfree( data->rbuffer );
-	if ( data->wbuffer ) kfree( data->wbuffer );
-	kfree( data );
+	struct proc_data *data = file->private_data;
+
+	if (data->on_close != NULL)
+		data->on_close(inode, file);
+	kfree(data->rbuffer);
+	kfree(data->wbuffer);
+	kfree(data);
 	return 0;
 }
 
diff --git a/drivers/net/wireless/airo_cs.c b/drivers/net/wireless/airo_cs.c
index bf25584..784de91 100644
--- a/drivers/net/wireless/airo_cs.c
+++ b/drivers/net/wireless/airo_cs.c
@@ -258,9 +258,7 @@ static void airo_detach(dev_link_t *link
 	
 	/* Unlink device structure, free pieces */
 	*linkp = link->next;
-	if (link->priv) {
-		kfree(link->priv);
-	}
+	kfree(link->priv);
 	kfree(link);
 	
 } /* airo_detach */
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index d570110..1fbe027 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -1653,8 +1653,7 @@ void stop_atmel_card(struct net_device *
 	unregister_netdev(dev);
 	remove_proc_entry("driver/atmel", NULL);
 	free_irq(dev->irq, dev);
-	if (priv->firmware)
-		kfree(priv->firmware);
+	kfree(priv->firmware);
 	if (freeres) {
 		/* PCMCIA frees this stuff, so only for PCI */
 	        release_region(dev->base_addr, 64);
@@ -2450,8 +2449,7 @@ static int atmel_ioctl(struct net_device
 			break;
 		}
 
-		if (priv->firmware)
-			kfree(priv->firmware);
+		kfree(priv->firmware);
 		
 		priv->firmware = new_firmware;
 		priv->firmware_length = com.len;
diff --git a/drivers/net/wireless/atmel_cs.c b/drivers/net/wireless/atmel_cs.c
index ff031a3..195cb36 100644
--- a/drivers/net/wireless/atmel_cs.c
+++ b/drivers/net/wireless/atmel_cs.c
@@ -259,8 +259,7 @@ static void atmel_detach(dev_link_t *lin
 
 	/* Unlink device structure, free pieces */
 	*linkp = link->next;
-	if (link->priv)
-		kfree(link->priv);
+	kfree(link->priv);
 	kfree(link);
 }
 
diff --git a/drivers/net/wireless/hostap/hostap_ioctl.c b/drivers/net/wireless/hostap/hostap_ioctl.c
index 53f5246..2617d70 100644
--- a/drivers/net/wireless/hostap/hostap_ioctl.c
+++ b/drivers/net/wireless/hostap/hostap_ioctl.c
@@ -552,7 +552,6 @@ static int prism2_ioctl_giwaplist(struct
 
 	kfree(addr);
 	kfree(qual);
-
 	return 0;
 }
 
@@ -3081,9 +3080,7 @@ static int prism2_ioctl_priv_download(lo
 	ret = local->func->download(local, param);
 
  out:
-	if (param != NULL)
-		kfree(param);
-
+	kfree(param);
 	return ret;
 }
 #endif /* PRISM2_DOWNLOAD_SUPPORT */
@@ -3890,9 +3887,7 @@ static int prism2_ioctl_priv_hostapd(loc
 	}
 
  out:
-	if (param != NULL)
-		kfree(param);
-
+	kfree(param);
 	return ret;
 }
 
diff --git a/drivers/net/wireless/prism54/islpci_dev.c b/drivers/net/wireless/prism54/islpci_dev.c
index 6c9584a..78bdb35 100644
--- a/drivers/net/wireless/prism54/islpci_dev.c
+++ b/drivers/net/wireless/prism54/islpci_dev.c
@@ -754,8 +754,7 @@ islpci_free_memory(islpci_private *priv)
 			pci_unmap_single(priv->pdev, buf->pci_addr,
 					 buf->size, PCI_DMA_FROMDEVICE);
 		buf->pci_addr = 0;
-		if (buf->mem)
-			kfree(buf->mem);
+		kfree(buf->mem);
 		buf->size = 0;
 		buf->mem = NULL;
         }
diff --git a/drivers/net/wireless/prism54/oid_mgt.c b/drivers/net/wireless/prism54/oid_mgt.c
index 12123e2..eea2f04 100644
--- a/drivers/net/wireless/prism54/oid_mgt.c
+++ b/drivers/net/wireless/prism54/oid_mgt.c
@@ -268,11 +268,10 @@ mgt_clean(islpci_private *priv)
 
 	if (!priv->mib)
 		return;
-	for (i = 0; i < OID_NUM_LAST; i++)
-		if (priv->mib[i]) {
-			kfree(priv->mib[i]);
-			priv->mib[i] = NULL;
-		}
+	for (i = 0; i < OID_NUM_LAST; i++) {
+		kfree(priv->mib[i]);
+		priv->mib[i] = NULL;
+	}
 	kfree(priv->mib);
 	priv->mib = NULL;
 }
diff --git a/drivers/net/wireless/strip.c b/drivers/net/wireless/strip.c
index 7bc7fc8..d25264b 100644
--- a/drivers/net/wireless/strip.c
+++ b/drivers/net/wireless/strip.c
@@ -860,12 +860,9 @@ static int allocate_buffers(struct strip
 		strip_info->mtu = dev->mtu = mtu;
 		return (1);
 	}
-	if (r)
-		kfree(r);
-	if (s)
-		kfree(s);
-	if (t)
-		kfree(t);
+	kfree(r);
+	kfree(s);
+	kfree(t);
 	return (0);
 }
 
@@ -922,13 +919,9 @@ static int strip_change_mtu(struct net_d
 	printk(KERN_NOTICE "%s: strip MTU changed fom %d to %d.\n",
 	       strip_info->dev->name, old_mtu, strip_info->mtu);
 
-	if (orbuff)
-		kfree(orbuff);
-	if (osbuff)
-		kfree(osbuff);
-	if (otbuff)
-		kfree(otbuff);
-
+	kfree(orbuff);
+	kfree(osbuff);
+	kfree(otbuff);
 	return 0;
 }
 
@@ -2498,18 +2491,13 @@ static int strip_close_low(struct net_de
 	/*
 	 * Free all STRIP frame buffers.
 	 */
-	if (strip_info->rx_buff) {
-		kfree(strip_info->rx_buff);
-		strip_info->rx_buff = NULL;
-	}
-	if (strip_info->sx_buff) {
-		kfree(strip_info->sx_buff);
-		strip_info->sx_buff = NULL;
-	}
-	if (strip_info->tx_buff) {
-		kfree(strip_info->tx_buff);
-		strip_info->tx_buff = NULL;
-	}
+	kfree(strip_info->rx_buff);
+	strip_info->rx_buff = NULL;
+	kfree(strip_info->sx_buff);
+	strip_info->sx_buff = NULL;
+	kfree(strip_info->tx_buff);
+	strip_info->tx_buff = NULL;
+
 	del_timer(&strip_info->idle_timer);
 	return 0;
 }
diff --git a/include/net/ax25.h b/include/net/ax25.h
index 30bb4a8..2250a18 100644
--- a/include/net/ax25.h
+++ b/include/net/ax25.h
@@ -237,8 +237,7 @@ typedef struct ax25_cb {
 static __inline__ void ax25_cb_put(ax25_cb *ax25)
 {
 	if (atomic_dec_and_test(&ax25->refcount)) {
-		if (ax25->digipeat)
-			kfree(ax25->digipeat);
+		kfree(ax25->digipeat);
 		kfree(ax25);
 	}
 }
diff --git a/include/net/netrom.h b/include/net/netrom.h
index a6bf6e0..a5ee53b 100644
--- a/include/net/netrom.h
+++ b/include/net/netrom.h
@@ -136,8 +136,7 @@ static __inline__ void nr_node_put(struc
 static __inline__ void nr_neigh_put(struct nr_neigh *nr_neigh)
 {
 	if (atomic_dec_and_test(&nr_neigh->refcount)) {
-		if (nr_neigh->digipeat != NULL)
-			kfree(nr_neigh->digipeat);
+		kfree(nr_neigh->digipeat);
 		kfree(nr_neigh);
 	}
 }
---
0.99.8.GIT


--- NEW FILE 1064-netdrvr-ne2k-pci-based-card-does-not-support-bus-mastering.txt ---
Subject: [PATCH] [netdrvr] ne2k-pci based card does not support bus-mastering.
From: Komuro <komurojun-mbn at nifty.com>
Date: 1130532955 -0400

pci_set_master is unnecessary.

Signed-off-by: komurojun-mbn at nifty.com
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/ne2k-pci.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

applies-to: 70aa8ba4864f8ee994b7f5278f5045af6a646d34
4f075707a9380592586d608a8d04dfbdb3c40339
diff --git a/drivers/net/ne2k-pci.c b/drivers/net/ne2k-pci.c
index e531a4e..d11821d 100644
--- a/drivers/net/ne2k-pci.c
+++ b/drivers/net/ne2k-pci.c
@@ -675,7 +675,6 @@ static int ne2k_pci_resume (struct pci_d
 	pci_set_power_state(pdev, 0);
 	pci_restore_state(pdev);
 	pci_enable_device(pdev);
-	pci_set_master(pdev);
 	NS8390_init(dev, 1);
 	netif_device_attach(dev);
 
---
0.99.8.GIT


--- NEW FILE 1065-ipw2200-Missing-kmalloc-check.txt ---
Subject: [PATCH] ipw2200: Missing kmalloc check
From: Panagiotis Issaris <panagiotis.issaris at gmail.com>
Date: 1125886450 +0200

The ipw2200 driver code in current GIT contains a kmalloc() followed by
a memset() without handling a possible memory allocation failure.

Signed-off-by: Panagiotis Issaris <panagiotis.issaris at gmail.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/ipw2200.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

applies-to: a18032b80383ba651236b7000028e2e1022ff0a2
ad18b0ea089928367185e13d11424aea91d4b41f
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index de4e6c2..3db0c32 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -4030,6 +4030,10 @@ static struct ipw_rx_queue *ipw_rx_queue
 	int i;
 
 	rxq = (struct ipw_rx_queue *)kmalloc(sizeof(*rxq), GFP_KERNEL);
+	if (unlikely(!rxq)) {
+		IPW_ERROR("memory allocation failed\n");
+		return NULL;
+	}
 	memset(rxq, 0, sizeof(*rxq));
 	spin_lock_init(&rxq->lock);
 	INIT_LIST_HEAD(&rxq->rx_free);
---
0.99.8.GIT


--- NEW FILE 1182-e1000-remove-warning-about-e1000_suspend.txt ---
Subject: [PATCH] e1000: remove warning about e1000_suspend
From: Martin J. Bligh <mbligh at mbligh.org>
Date: 1130537684 -0700

e1000_suspend is only used under #ifdef CONFIG_PM.  Move the declaration of
it to be the same way, just like e1000_resume, otherwise gcc whines on
compile.  I offer as evidence:

	static struct pci_driver e1000_driver = {
 	       .name     = e1000_driver_name,
 	      .id_table = e1000_pci_tbl,
  	      .probe    = e1000_probe,
  	      .remove   = __devexit_p(e1000_remove),
 	      /* Power Managment Hooks */
	#ifdef CONFIG_PM
 	       .suspend  = e1000_suspend,
 	       .resume   = e1000_resume
	#endif
	};

Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 78bc640acacb8faeb621c51296e99dbb0533a147
b6a1d5f88473138497d8694ddf174e8e91300068
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index 6b72f6a..a0023f3 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -4193,6 +4193,7 @@ e1000_set_spd_dplx(struct e1000_adapter 
 	return 0;
 }
 
+#ifdef CONFIG_PM
 static int
 e1000_suspend(struct pci_dev *pdev, pm_message_t state)
 {
@@ -4289,7 +4290,6 @@ e1000_suspend(struct pci_dev *pdev, pm_m
 	return 0;
 }
 
-#ifdef CONFIG_PM
 static int
 e1000_resume(struct pci_dev *pdev)
 {
---
0.99.8.GIT


--- NEW FILE 1183-eepro.c-module_param_array-cleanup.txt ---
Subject: [PATCH] eepro.c: module_param_array cleanup
From: Florin Malita <fmalita at gmail.com>
Date: 1130537686 -0700

num_params is unused (and unusable in this form).

Signed-off-by: Florin Malita <fmalita at gmail.com>
Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/eepro.c |    7 +++----
 1 files changed, 3 insertions(+), 4 deletions(-)

applies-to: 30d0b9771aae18d62c927cd257643a034f02bacb
a1bfcd97414d3e9b3c96f27d9b1a1e76c9543ba6
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index dcb3028..1ce2c67 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -1797,10 +1797,9 @@ MODULE_AUTHOR("Pascal Dupuis and others"
 MODULE_DESCRIPTION("Intel i82595 ISA EtherExpressPro10/10+ driver");
 MODULE_LICENSE("GPL");
 
-static int num_params;
-module_param_array(io, int, &num_params, 0);
-module_param_array(irq, int, &num_params, 0);
-module_param_array(mem, int, &num_params, 0);
+module_param_array(io, int, NULL, 0);
+module_param_array(irq, int, NULL, 0);
+module_param_array(mem, int, NULL, 0);
 module_param(autodetect, int, 0);
 MODULE_PARM_DESC(io, "EtherExpress Pro/10 I/O base addres(es)");
 MODULE_PARM_DESC(irq, "EtherExpress Pro/10 IRQ number(s)");
---
0.99.8.GIT


--- NEW FILE 1184-b44-fix-suspend-resume.txt ---
Subject: [PATCH] b44: fix suspend/resume
From: Pavel Machek <pavel at ucw.cz>
Date: 1130537687 -0700

Fix suspend/resume on b44 by freeing/reacquiring irq.  Otherwise it hangs
on resume.

Signed-off-by: Pavel Machek <pavel at suse.cz>
Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

applies-to: 139ee353f51a2c0700e515f0bd02d8eb000a7745
46e178535836dcd7ef92f179218628d101892c59
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 5485e3b..0ee3e27 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -2041,6 +2041,8 @@ static int b44_suspend(struct pci_dev *p
 	b44_free_rings(bp);
 
 	spin_unlock_irq(&bp->lock);
+
+	free_irq(dev->irq, dev);
 	pci_disable_device(pdev);
 	return 0;
 }
@@ -2057,6 +2059,9 @@ static int b44_resume(struct pci_dev *pd
 	if (!netif_running(dev))
 		return 0;
 
+	if (request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev))
+		printk(KERN_ERR PFX "%s: request_irq failed\n", dev->name);
+
 	spin_lock_irq(&bp->lock);
 
 	b44_init_rings(bp);
---
0.99.8.GIT


--- NEW FILE 1185-e1000-use-vmalloc_node.txt ---
Subject: [PATCH] e1000: use vmalloc_node()
From: Ravikiran G Thirumalai <kiran at scalex86.org>
Date: 1130537689 -0700

Allocate node local tx and rx descriptors for the e1000 driver

Signed-off-by: Ravikiran Thirumalai <kiran at scalex86.org>
Cc: Christoph Lameter <clameter at engr.sgi.com>
Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_main.c |    5 +++--
 1 files changed, 3 insertions(+), 2 deletions(-)

applies-to: db323b41078da50d3cd56a6f99da919bc619e4eb
a7ec15da65ab64c5f97beedc4ff21cf3e0ae71c0
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index a0023f3..d97ad89 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -1149,7 +1149,8 @@ e1000_setup_tx_resources(struct e1000_ad
 	int size;
 
 	size = sizeof(struct e1000_buffer) * txdr->count;
-	txdr->buffer_info = vmalloc(size);
+
+	txdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
 	if(!txdr->buffer_info) {
 		DPRINTK(PROBE, ERR,
 		"Unable to allocate memory for the transmit descriptor ring\n");
@@ -1366,7 +1367,7 @@ e1000_setup_rx_resources(struct e1000_ad
 	int size, desc_len;
 
 	size = sizeof(struct e1000_buffer) * rxdr->count;
-	rxdr->buffer_info = vmalloc(size);
+	rxdr->buffer_info = vmalloc_node(size, pcibus_to_node(pdev->bus));
 	if (!rxdr->buffer_info) {
 		DPRINTK(PROBE, ERR,
 		"Unable to allocate memory for the receive descriptor ring\n");
---
0.99.8.GIT


--- NEW FILE 1186-revert-orinoco-Information-leakage-due-to-incorrect-padding.txt ---
Subject: [PATCH] revert "orinoco: Information leakage due to incorrect padding"
From: Andrew Morton <akpm at osdl.org>
Date: 1130537691 -0700

Cc: Alan Cox <alan at redhat.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/orinoco.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

applies-to: 05cb18e46286e5343a795c71890115a59e8c30bf
63f57fb69b017230c77c40f1713e40885ae6d159
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index d3d4ec9..70a3477 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -490,7 +490,8 @@ static int orinoco_xmit(struct sk_buff *
 		return 0;
 	}
 
-	/* Check packet length, pad short packets, round up odd length */
+	/* Length of the packet body */
+	/* FIXME: what if the skb is smaller than this? */
 	len = max_t(int, ALIGN(skb->len, 2), ETH_ZLEN);
 	skb = skb_padto(skb, len);
 	if (skb == NULL)
@@ -547,7 +548,8 @@ static int orinoco_xmit(struct sk_buff *
 		p = skb->data;
 	}
 
-	err = hermes_bap_pwrite(hw, USER_BAP, p, data_len,
+	/* Round up for odd length packets */
+	err = hermes_bap_pwrite(hw, USER_BAP, p, ALIGN(data_len, 2),
 				txfid, data_off);
 	if (err) {
 		printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
---
0.99.8.GIT


--- NEW FILE 1187-Better-fixup-for-the-orinoco-driver.txt ---
Subject: [PATCH] Better fixup for the orinoco driver
From: Alan Cox <alan at lxorguk.ukuu.org.uk>
Date: 1130537692 -0700

The latest kernel added a pretty ugly fix for the orinoco etherleak bug
which contains bogus skb->len checks already done by the caller and causes
copies of all odd sized frames (which are quite common)

While the skb->len check should be ripped out the other fix is harder to do
properly so I'm proposing for this the -mm tree only until next 2.6.x so
that it gets tested.

Instead of copying buffers around blindly this code implements a padding
aware version of the hermes buffer writing function which does padding as
the buffer is loaded and thus more cleanly and without bogus 1.5K copies.

Signed-off-by: Alan Cox <alan at redhat.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/hermes.c  |   38 ++++++++++++++++++++++++++++++++++++++
 drivers/net/wireless/hermes.h  |    2 ++
 drivers/net/wireless/orinoco.c |   11 +++++++++--
 3 files changed, 49 insertions(+), 2 deletions(-)

applies-to: d30d9f0c237b000b171e9e5918d0337268cf0f8b
2c36ed22c6f64de94c6c3b7258dd7285bb093401
diff --git a/drivers/net/wireless/hermes.c b/drivers/net/wireless/hermes.c
index eba0d9d..579480d 100644
--- a/drivers/net/wireless/hermes.c
+++ b/drivers/net/wireless/hermes.c
@@ -444,6 +444,43 @@ int hermes_bap_pwrite(hermes_t *hw, int 
 	return err;
 }
 
+/* Write a block of data to the chip's buffer with padding if
+ * neccessary, via the BAP. Synchronization/serialization is the
+ * caller's problem. len must be even.
+ *
+ * Returns: < 0 on internal failure (errno), 0 on success, > 0 on error from firmware
+ */
+int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf, unsigned data_len, unsigned len,
+		      u16 id, u16 offset)
+{
+	int dreg = bap ? HERMES_DATA1 : HERMES_DATA0;
+	int err = 0;
+
+	if (len < 0 || len % 2 || data_len > len)
+		return -EINVAL;
+
+	err = hermes_bap_seek(hw, bap, id, offset);
+	if (err)
+		goto out;
+
+	/* Transfer all the complete words of data */
+	hermes_write_words(hw, dreg, buf, data_len/2);
+	/* If there is an odd byte left over pad and transfer it */
+	if (data_len & 1) {
+		u8 end[2];
+		end[1] = 0;
+		end[0] = ((unsigned char *)buf)[data_len - 1];
+		hermes_write_words(hw, dreg, end, 1);
+		data_len ++;
+	}
+	/* Now send zeros for the padding */
+	if (data_len < len)
+		hermes_clear_words(hw, dreg, (len - data_len) / 2);
+	/* Complete */
+ out:
+	return err;
+}
+
 /* Read a Length-Type-Value record from the card.
  *
  * If length is NULL, we ignore the length read from the card, and
@@ -531,6 +568,7 @@ EXPORT_SYMBOL(hermes_allocate);
 
 EXPORT_SYMBOL(hermes_bap_pread);
 EXPORT_SYMBOL(hermes_bap_pwrite);
+EXPORT_SYMBOL(hermes_bap_pwrite_pad);
 EXPORT_SYMBOL(hermes_read_ltv);
 EXPORT_SYMBOL(hermes_write_ltv);
 
diff --git a/drivers/net/wireless/hermes.h b/drivers/net/wireless/hermes.h
index ad28e32..a6bd472 100644
--- a/drivers/net/wireless/hermes.h
+++ b/drivers/net/wireless/hermes.h
@@ -376,6 +376,8 @@ int hermes_bap_pread(hermes_t *hw, int b
 		       u16 id, u16 offset);
 int hermes_bap_pwrite(hermes_t *hw, int bap, const void *buf, unsigned len,
 			u16 id, u16 offset);
+int hermes_bap_pwrite_pad(hermes_t *hw, int bap, const void *buf,
+			unsigned data_len, unsigned len, u16 id, u16 offset);
 int hermes_read_ltv(hermes_t *hw, int bap, u16 rid, unsigned buflen,
 		    u16 *length, void *buf);
 int hermes_write_ltv(hermes_t *hw, int bap, u16 rid,
diff --git a/drivers/net/wireless/orinoco.c b/drivers/net/wireless/orinoco.c
index 70a3477..488ab06 100644
--- a/drivers/net/wireless/orinoco.c
+++ b/drivers/net/wireless/orinoco.c
@@ -542,14 +542,21 @@ static int orinoco_xmit(struct sk_buff *
 			stats->tx_errors++;
 			goto fail;
 		}
+		/* Actual xfer length - allow for padding */
+		len = ALIGN(data_len, 2);
+		if (len < ETH_ZLEN - ETH_HLEN)
+			len = ETH_ZLEN - ETH_HLEN;
 	} else { /* IEEE 802.3 frame */
 		data_len = len + ETH_HLEN;
 		data_off = HERMES_802_3_OFFSET;
 		p = skb->data;
+		/* Actual xfer length - round up for odd length packets */
+		len = ALIGN(data_len, 2);
+		if (len < ETH_ZLEN)
+			len = ETH_ZLEN;
 	}
 
-	/* Round up for odd length packets */
-	err = hermes_bap_pwrite(hw, USER_BAP, p, ALIGN(data_len, 2),
+	err = hermes_bap_pwrite_pad(hw, USER_BAP, p, data_len, len,
 				txfid, data_off);
 	if (err) {
 		printk(KERN_ERR "%s: Error %d writing packet to BAP\n",
---
0.99.8.GIT


--- NEW FILE 1188-e1000-Fixes-e1000_suspend-warning-when-CONFIG_PM-is-not-enabled.txt ---
Subject: [PATCH] e1000: Fixes e1000_suspend warning when CONFIG_PM is not enabled
From: Ashutosh Naik <ashutosh_naik at adaptec.com>
Date: 1130537693 -0700

drivers/net/e1000/e1000_main.c:3645: warning: `e1000_suspend' defined
but not used

Signed-off-by: Ashutosh Naik <ashutosh_naik at adaptec.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/e1000/e1000_main.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: bf8ab970180df5abe28d0c75d993a86a063bd8d5
977e74b5f60de3df9831897b726c16870878eee4
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index d97ad89..efbbda7 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -191,8 +191,8 @@ static void e1000_vlan_rx_add_vid(struct
 static void e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid);
 static void e1000_restore_vlan(struct e1000_adapter *adapter);
 
-static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
 #ifdef CONFIG_PM
+static int e1000_suspend(struct pci_dev *pdev, pm_message_t state);
 static int e1000_resume(struct pci_dev *pdev);
 #endif
 
---
0.99.8.GIT


--- NEW FILE 1306-Add-modalias-for-pmac-network-drivers.txt ---
Subject: [PATCH] Add modalias for pmac network drivers
From: Olaf Hering <olh at suse.de>
Date: 1130546781 -0700

mesh, mac53c94 and airport already have an entry.  Add the network drivers
for pmac.

Signed-off-by: Olaf Hering <olh at suse.de>
Acked-by: Benjamin Herrenschmidt <benh at kernel.crashing.org>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Paul Mackerras <paulus at samba.org>

---

 drivers/net/bmac.c |    1 +
 drivers/net/mace.c |    1 +
 2 files changed, 2 insertions(+), 0 deletions(-)

applies-to: 41e79b5d302ddb08745e93891a6dd4e4a00c208a
8c9795ba01d02b043ce2d9eeb0fa908c07e5fb42
diff --git a/drivers/net/bmac.c b/drivers/net/bmac.c
index 60dba4a..0ee2889 100644
--- a/drivers/net/bmac.c
+++ b/drivers/net/bmac.c
@@ -1658,6 +1658,7 @@ static struct of_device_id bmac_match[] 
 	},
 	{},
 };
+MODULE_DEVICE_TABLE (of, bmac_match);
 
 static struct macio_driver bmac_driver = 
 {
diff --git a/drivers/net/mace.c b/drivers/net/mace.c
index 81d0a26..f2fc1f2 100644
--- a/drivers/net/mace.c
+++ b/drivers/net/mace.c
@@ -1016,6 +1016,7 @@ static struct of_device_id mace_match[] 
 	},
 	{},
 };
+MODULE_DEVICE_TABLE (of, mace_match);
 
 static struct macio_driver mace_driver = 
 {
---
0.99.8.GIT


--- NEW FILE 1310-mv643xx_eth_showsram-Added-information-message-when-using-the-SRAM.txt ---
Subject: [PATCH] mv643xx_eth_showsram: Added information message when using the SRAM
From: Nicolas DET <nd at bplan-gmbh.de>
Date: 1130546790 -0700

Added information message when using the SRAM in mv643xx_eth_probe()

Signed-off-by: Nicolas DET <det.nicolas at free.fr>
Signed-off-by: Sven Luther <sl at bplan-gmbh.de>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Paul Mackerras <paulus at samba.org>

---

 drivers/net/mv643xx_eth.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

applies-to: eab0004612f4e94cb485510a9f6adabd549a8892
b1529871f4270d10a0d1a9c998be162f0123d8f1
diff --git a/drivers/net/mv643xx_eth.c b/drivers/net/mv643xx_eth.c
index 25c9a99..8fbba21 100644
--- a/drivers/net/mv643xx_eth.c
+++ b/drivers/net/mv643xx_eth.c
@@ -1533,6 +1533,9 @@ static int mv643xx_eth_probe(struct devi
 	printk(KERN_NOTICE "%s: RX NAPI Enabled \n", dev->name);
 #endif
 
+	if (mp->tx_sram_size > 0)
+		printk(KERN_NOTICE "%s: Using SRAM\n", dev->name);
+
 	return 0;
 
 out:
---
0.99.8.GIT


--- NEW FILE 1371-s2io-iomem-annotations.txt ---
Subject: [PATCH] s2io iomem annotations
From: Al Viro <viro at ftp.linux.org.uk>
Date: 1130564187 +0100

Signed-off-by: Al Viro <viro at zeniv.linux.org.uk>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/s2io.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

applies-to: cfa290c7ca6b63f33b2b4624695596f38bcda2fd
7533624527b9afa5585ca43ba534758052d848e5
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index d303d16..62d5041 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -3045,7 +3045,7 @@ int s2io_set_swapper(nic_t * sp)
 
 int wait_for_msix_trans(nic_t *nic, int i)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u64 val64;
 	int ret = 0, cnt = 0;
 
@@ -3066,7 +3066,7 @@ int wait_for_msix_trans(nic_t *nic, int 
 
 void restore_xmsi_data(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u64 val64;
 	int i;
 
@@ -3084,7 +3084,7 @@ void restore_xmsi_data(nic_t *nic)
 
 void store_xmsi_data(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u64 val64, addr, data;
 	int i;
 
@@ -3107,7 +3107,7 @@ void store_xmsi_data(nic_t *nic)
 
 int s2io_enable_msi(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u16 msi_ctrl, msg_val;
 	struct config_param *config = &nic->config;
 	struct net_device *dev = nic->dev;
@@ -3157,7 +3157,7 @@ int s2io_enable_msi(nic_t *nic)
 
 int s2io_enable_msi_x(nic_t *nic)
 {
-	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
+	XENA_dev_config_t __iomem *bar0 = nic->bar0;
 	u64 tx_mat, rx_mat;
 	u16 msi_control; /* Temp variable */
 	int ret, i, j, msix_indx = 1;
---
0.99.8.GIT


--- NEW FILE 1385-drivers-net-tg3-Use-the-DMA_-32-64-BIT_MASK-constants.txt ---
Subject: [PATCH] drivers/net/tg3: Use the DMA_{32,64}BIT_MASK constants
From: Tobias Klauser <tklauser at nuerscht.ch>
Date: 1130591366 +0200

This one from my DMA_{32,64}BIT_MASK series did not seem to make it
through to upstream.

Use the DMA_{32,64}BIT_MASK constants from dma-mapping.h when calling
pci_set_dma_mask() or pci_set_consistent_dma_mask()
This patch includes dma-mapping.h explicitly because it caused errors
on some architectures otherwise.
See http://marc.theaimsgroup.com/?t=108001993000001&r=1&w=2 for details

Signed-off-by: Tobias Klauser <tklauser at nuerscht.ch>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/tg3.c |    7 ++++---
 1 files changed, 4 insertions(+), 3 deletions(-)

applies-to: c5fe78bf8b9aaf393cee878aaf89241fe40f8ba5
f9a5f7d3f3319aac02a7a36a2fea10bd33c3d16a
diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c
index b547233..1828a6b 100644
--- a/drivers/net/tg3.c
+++ b/drivers/net/tg3.c
@@ -37,6 +37,7 @@
 #include <linux/tcp.h>
 #include <linux/workqueue.h>
 #include <linux/prefetch.h>
+#include <linux/dma-mapping.h>
 
 #include <net/checksum.h>
 
@@ -10522,17 +10523,17 @@ static int __devinit tg3_init_one(struct
 	}
 
 	/* Configure DMA attributes. */
-	err = pci_set_dma_mask(pdev, 0xffffffffffffffffULL);
+	err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
 	if (!err) {
 		pci_using_dac = 1;
-		err = pci_set_consistent_dma_mask(pdev, 0xffffffffffffffffULL);
+		err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
 		if (err < 0) {
 			printk(KERN_ERR PFX "Unable to obtain 64 bit DMA "
 			       "for consistent allocations\n");
 			goto err_out_free_res;
 		}
 	} else {
-		err = pci_set_dma_mask(pdev, 0xffffffffULL);
+		err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
 		if (err) {
 			printk(KERN_ERR PFX "No usable DMA configuration, "
 			       "aborting.\n");
---
0.99.8.GIT


--- NEW FILE 1387-prism54-Free-skb-after-disabling-interrupts.txt ---
Subject: [PATCH] prism54: Free skb after disabling interrupts
From: Patrick McHardy <kaber at trash.net>
Date: 1130589099 +0100

The dev_kfree_skb in islpci_eth_transmit happens while irqs are still
disabled, so either dev_kfree_skb_irq needs to be used or the skb
needs to be freed after irqs have been enabled again. This patch
should fix it.

Signed-off-by: Patrick McHardy <kaber at trash.net>
Signed-off-by: Daniel Drake <dsd at gentoo.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/prism54/islpci_eth.c |    6 ++----
 1 files changed, 2 insertions(+), 4 deletions(-)

applies-to: e104862f5bf9c873be2599b4f8e9a7f93644bda4
e71180f3689e00c5a1095925352a72dacdd62e34
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 0975dd4..3b49efa 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -241,12 +241,10 @@ islpci_eth_transmit(struct sk_buff *skb,
 	return 0;
 
       drop_free:
-	/* free the skbuf structure before aborting */
-	dev_kfree_skb(skb);
-	skb = NULL;
-
 	priv->statistics.tx_dropped++;
 	spin_unlock_irqrestore(&priv->slock, flags);
+	dev_kfree_skb(skb);
+	skb = NULL;
 	return err;
 }
 
---
0.99.8.GIT


--- NEW FILE 1736-fec_8xx-Remove-dependency-on-NETTA-NETPHONE.txt ---
Subject: [PATCH] fec_8xx: Remove dependency on NETTA & NETPHONE
From: Pantelis Antoniou <pantelis.antoniou at gmail.com>
Date: 1130624595 +0300

The following patch removes the dependency of the fec_8xx driver on
the NETTA & NETPHONE boards. Other people use the driver too, and
we await their board support patches.

Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/fec_8xx/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: a530f8f311ec36de89d8435cc116011d84f7f1ba
b90bd04d419dd317b16dce83f5595e96597c05be
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index db36ac3..de04d68 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -1,6 +1,6 @@
 config FEC_8XX
 	tristate "Motorola 8xx FEC driver"
-	depends on NET_ETHERNET && 8xx && (NETTA || NETPHONE)
+	depends on NET_ETHERNET
 	select MII
 
 config FEC_8XX_GENERIC_PHY
---
0.99.8.GIT


--- NEW FILE 1737-fec_8xx-Add-support-for-Intel-PHY-LX971.txt ---
Subject: [PATCH] fec_8xx: Add support for Intel PHY LX971
From: Pantelis Antoniou <pantelis.antoniou at gmail.com>
Date: 1130624634 +0300

The following patch add support for the Intel LX971 PHY.

Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/fec_8xx/Kconfig   |    6 ++++++
 drivers/net/fec_8xx/fec_mii.c |   42 +++++++++++++++++++++++++++++++++++++++++
 2 files changed, 48 insertions(+), 0 deletions(-)

applies-to: 10c5e6feb03c200db9f971d712f89c48627e89e8
23da0c20ef1c1f0432f373e0e2233a6b6ab2678f
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index de04d68..4560026 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -12,3 +12,9 @@ config FEC_8XX_DM9161_PHY
 	bool "Support DM9161 PHY"
 	depends on FEC_8XX
 	default n
+
+config FEC_8XX_LXT971_PHY
+	bool "Support LXT971/LXT972 PHY"
+	depends on FEC_8XX
+	default n
+
diff --git a/drivers/net/fec_8xx/fec_mii.c b/drivers/net/fec_8xx/fec_mii.c
index 803eb09..3b44ac1 100644
--- a/drivers/net/fec_8xx/fec_mii.c
+++ b/drivers/net/fec_8xx/fec_mii.c
@@ -203,6 +203,39 @@ static void dm9161_shutdown(struct net_d
 
 #endif
 
+#ifdef CONFIG_FEC_8XX_LXT971_PHY
+
+/* Support for LXT971/972 PHY */
+
+#define MII_LXT971_PCR		16 /* Port Control Register */
+#define MII_LXT971_SR2		17 /* Status Register 2 */
+#define MII_LXT971_IER		18 /* Interrupt Enable Register */
+#define MII_LXT971_ISR		19 /* Interrupt Status Register */
+#define MII_LXT971_LCR		20 /* LED Control Register */
+#define MII_LXT971_TCR		30 /* Transmit Control Register */
+
+static void lxt971_startup(struct net_device *dev)
+{
+	struct fec_enet_private *fep = netdev_priv(dev);
+
+	fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x00F2);
+}
+
+static void lxt971_ack_int(struct net_device *dev)
+{
+	struct fec_enet_private *fep = netdev_priv(dev);
+
+	fec_mii_read(dev, fep->mii_if.phy_id, MII_LXT971_ISR);
+}
+
+static void lxt971_shutdown(struct net_device *dev)
+{
+	struct fec_enet_private *fep = netdev_priv(dev);
+
+	fec_mii_write(dev, fep->mii_if.phy_id, MII_LXT971_IER, 0x0000);
+}
+#endif
+
 /**********************************************************************************/
 
 static const struct phy_info phy_info[] = {
@@ -215,6 +248,15 @@ static const struct phy_info phy_info[] 
 	 .shutdown = dm9161_shutdown,
 	 },
 #endif
+#ifdef CONFIG_FEC_8XX_LXT971_PHY
+	{
+	 .id = 0x0001378e,
+	 .name = "LXT971/972",
+	 .startup = lxt971_startup,
+	 .ack_int = lxt971_ack_int,
+	 .shutdown = lxt971_shutdown,
+	},
+#endif
 #ifdef CONFIG_FEC_8XX_GENERIC_PHY
 	{
 	 .id = 0,
---
0.99.8.GIT


--- NEW FILE 1902-m32r-SMC91x-driver-update.txt ---
Subject: [PATCH] m32r: SMC91x driver update
From: Hirokazu Takata <takata at linux-m32r.org>
Date: 1130713206 -0800

Update SMC91x driver for m32r.

- Remove needless NONCACHE_OFFSET adjustment.
  > [PATCH 2.6.14-rc4] m32r: NONCACHE_OFFSET in _port2addr
  > Change _port2addr() not to add NONCACHE_OFFSET.
  > Adding NONCACHE_OFFSET requires needless address adjusting by a driver
  > using ioremap() like a SMC91x driver.

- Fix lots of warnings as following:
/usr/src/ctest/git/kernel/drivers/net/smc91x.c: In function `smc_reset':
/usr/src/ctest/git/kernel/drivers/net/smc91x.c:324: warning: passing arg 2 of `_outw' makes integer from pointer without a cast
/usr/src/ctest/git/kernel/drivers/net/smc91x.c:325: warning: passing arg 2 of `_outw' makes integer from pointer without a cast
/usr/src/ctest/git/kernel/drivers/net/smc91x.c:341: warning: passing arg 2 of `_outw' makes integer from pointer without a cast
/usr/src/ctest/git/kernel/drivers/net/smc91x.c:342: warning: passing arg 2 of `_outw' makes integer from pointer without a cast
  :
/usr/src/ctest/git/kernel/drivers/net/smc91x.c:1915: warning: passing arg 1 of `_inw' makes integer from pointer without a cast
/usr/src/ctest/git/kernel/drivers/net/smc91x.c:1915: warning: passing arg 1 of `_inw' makes integer from pointer without a cast

Signed-off-by: Hayato Fujiwara <fujiwara at linux-m32r.org>
Signed-off-by: Hirokazu Takata <takata at linux-m32r.org>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 arch/m32r/kernel/io_m32700ut.c |    6 +++---
 arch/m32r/kernel/io_mappi2.c   |    9 ++++-----
 arch/m32r/kernel/io_mappi3.c   |    7 +++----
 arch/m32r/kernel/io_opsput.c   |    6 +++---
 drivers/net/smc91x.h           |   12 ++++++------
 5 files changed, 19 insertions(+), 21 deletions(-)

applies-to: 7a05a732894cc7911c36598238f6d948655c67a0
f3ac9fbf7a0b9493377ee88d9b5b2933ff3f7ade
diff --git a/arch/m32r/kernel/io_m32700ut.c b/arch/m32r/kernel/io_m32700ut.c
index e545b06..eda9f96 100644
--- a/arch/m32r/kernel/io_m32700ut.c
+++ b/arch/m32r/kernel/io_m32700ut.c
@@ -64,11 +64,11 @@ static inline void *__port2addr_ata(unsi
  * from 0x10000000 to 0x13ffffff on physical address.
  * The base address of LAN controller(LAN91C111) is 0x300.
  */
-#define LAN_IOSTART	0x300
-#define LAN_IOEND	0x320
+#define LAN_IOSTART	0xa0000300
+#define LAN_IOEND	0xa0000320
 static inline void *_port2addr_ne(unsigned long port)
 {
-	return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+	return (void *)(port + 0x10000000);
 }
 static inline void *_port2addr_usb(unsigned long port)
 {
diff --git a/arch/m32r/kernel/io_mappi2.c b/arch/m32r/kernel/io_mappi2.c
index d04e90a..df3c729 100644
--- a/arch/m32r/kernel/io_mappi2.c
+++ b/arch/m32r/kernel/io_mappi2.c
@@ -36,9 +36,6 @@ static inline void *_port2addr(unsigned 
 	return (void *)(port | (NONCACHE_OFFSET));
 }
 
-#define LAN_IOSTART	0x300
-#define LAN_IOEND	0x320
-
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 static inline void *__port2addr_ata(unsigned long port)
 {
@@ -59,15 +56,17 @@ static inline void *__port2addr_ata(unsi
 }
 #endif
 
+#define LAN_IOSTART	0xa0000300
+#define LAN_IOEND	0xa0000320
 #ifdef CONFIG_CHIP_OPSP
 static inline void *_port2addr_ne(unsigned long port)
 {
-	return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+	return (void *)(port + 0x10000000);
 }
 #else
 static inline void *_port2addr_ne(unsigned long port)
 {
-	return (void *)(port + NONCACHE_OFFSET + 0x04000000);
+	return (void *)(port + 0x04000000);
 }
 #endif
 static inline void *_port2addr_usb(unsigned long port)
diff --git a/arch/m32r/kernel/io_mappi3.c b/arch/m32r/kernel/io_mappi3.c
index c80bde6..6716ffe 100644
--- a/arch/m32r/kernel/io_mappi3.c
+++ b/arch/m32r/kernel/io_mappi3.c
@@ -36,9 +36,6 @@ static inline void *_port2addr(unsigned 
 	return (void *)(port + NONCACHE_OFFSET);
 }
 
-#define LAN_IOSTART	0x300
-#define LAN_IOEND	0x320
-
 #if defined(CONFIG_IDE) && !defined(CONFIG_M32R_CFC)
 static inline void *__port2addr_ata(unsigned long port)
 {
@@ -59,9 +56,11 @@ static inline void *__port2addr_ata(unsi
 }
 #endif
 
+#define LAN_IOSTART	0xa0000300
+#define LAN_IOEND	0xa0000320
 static inline void *_port2addr_ne(unsigned long port)
 {
-	return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+	return (void *)(port + 0x10000000);
 }
 
 static inline void *_port2addr_usb(unsigned long port)
diff --git a/arch/m32r/kernel/io_opsput.c b/arch/m32r/kernel/io_opsput.c
index 5ac84b1..4793bd1 100644
--- a/arch/m32r/kernel/io_opsput.c
+++ b/arch/m32r/kernel/io_opsput.c
@@ -44,11 +44,11 @@ static inline void *_port2addr(unsigned 
  * from 0x10000000 to 0x13ffffff on physical address.
  * The base address of LAN controller(LAN91C111) is 0x300.
  */
-#define LAN_IOSTART	0x300
-#define LAN_IOEND	0x320
+#define LAN_IOSTART	0xa0000300
+#define LAN_IOEND	0xa0000320
 static inline void *_port2addr_ne(unsigned long port)
 {
-	return (void *)(port + NONCACHE_OFFSET + 0x10000000);
+	return (void *)(port + 0x10000000);
 }
 static inline void *_port2addr_usb(unsigned long port)
 {
diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h
index ac9ce65..817f200 100644
--- a/drivers/net/smc91x.h
+++ b/drivers/net/smc91x.h
@@ -230,12 +230,12 @@ SMC_outw(u16 val, void __iomem *ioaddr, 
 #define SMC_CAN_USE_16BIT	1
 #define SMC_CAN_USE_32BIT	0
 
-#define SMC_inb(a, r)		inb((a) + (r) - 0xa0000000)
-#define SMC_inw(a, r)		inw((a) + (r) - 0xa0000000)
-#define SMC_outb(v, a, r)	outb(v, (a) + (r) - 0xa0000000)
-#define SMC_outw(v, a, r)	outw(v, (a) + (r) - 0xa0000000)
-#define SMC_insw(a, r, p, l)	insw((a) + (r) - 0xa0000000, p, l)
-#define SMC_outsw(a, r, p, l)	outsw((a) + (r) - 0xa0000000, p, l)
+#define SMC_inb(a, r)		inb((u32)a) + (r))
+#define SMC_inw(a, r)		inw(((u32)a) + (r))
+#define SMC_outb(v, a, r)	outb(v, ((u32)a) + (r))
+#define SMC_outw(v, a, r)	outw(v, ((u32)a) + (r))
+#define SMC_insw(a, r, p, l)	insw(((u32)a) + (r), p, l)
+#define SMC_outsw(a, r, p, l)	outsw(((u32)a) + (r), p, l)
 
 #define set_irq_type(irq, type)	do {} while(0)
 
---
0.99.8.GIT


--- NEW FILE 1923-remove-some-more-check_region-stuff.txt ---
Subject: [PATCH] remove some more check_region stuff
From: Jeff Garzik <jgarzik at pobox.com>
Date: 1130713311 -0800

Removed some more references to check_region().

I checked these changes into the 'checkreg' branch of
rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git

The only valid references remaining are in:
drivers/scsi/advansys.c
drivers/scsi/BusLogic.c
drivers/cdrom/sbpcd.c
sound/oss/pss.c

  Remove last vestiges of ide_check_region()
  drivers/char/specialix: trim trailing whitespace
  drivers/char/specialix: eliminate use of check_region()
  Remove outdated and unused references to check_region()
  [sound oss] remove check_region() usage from cs4232, wavfront
  [netdrvr eepro] trim trailing whitespace
  [netdrvr eepro] remove check_region() usage

Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 Documentation/i2c/writing-clients |    1 
 arch/ppc/platforms/hdpu.c         |    5 -
 arch/sparc/kernel/pcic.c          |    4 
 drivers/char/specialix.c          |  342 ++++++++++++++++++-------------------
 drivers/net/eepro.c               |   50 +++--
 include/asm-m68k/sun3xflop.h      |    2 
 include/asm-m68knommu/ide.h       |    7 -
 include/asm-parisc/ide.h          |    1 
 include/asm-sparc/floppy.h        |    2 
 sound/oss/cs4232.c                |    6 -
 sound/oss/wavfront.c              |   38 +++-
 11 files changed, 230 insertions(+), 228 deletions(-)

applies-to: 752720b8327e4bac9b21da088f1530cdbb43739d
d61780c0d384939ef31c46b47442854d5def4623
diff --git a/Documentation/i2c/writing-clients b/Documentation/i2c/writing-clients
index e94d9c6..cff7b65 100644
--- a/Documentation/i2c/writing-clients
+++ b/Documentation/i2c/writing-clients
@@ -273,6 +273,7 @@ For now, you can ignore the `flags' para
     if (is_isa) {
 
       /* Discard immediately if this ISA range is already used */
+      /* FIXME: never use check_region(), only request_region() */
       if (check_region(address,FOO_EXTENT))
         goto ERROR0;
 
diff --git a/arch/ppc/platforms/hdpu.c b/arch/ppc/platforms/hdpu.c
index ff37968..eed4ff6 100644
--- a/arch/ppc/platforms/hdpu.c
+++ b/arch/ppc/platforms/hdpu.c
@@ -609,11 +609,6 @@ static void parse_bootinfo(unsigned long
 }
 
 #if defined(CONFIG_BLK_DEV_IDE) || defined(CONFIG_BLK_DEV_IDE_MODULE)
-static int hdpu_ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-	return check_region(from, extent);
-}
-
 static void
 hdpu_ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
 {
diff --git a/arch/sparc/kernel/pcic.c b/arch/sparc/kernel/pcic.c
index 36a4069..25e31d5 100644
--- a/arch/sparc/kernel/pcic.c
+++ b/arch/sparc/kernel/pcic.c
@@ -497,8 +497,8 @@ static void pcic_map_pci_device(struct l
 				 * CheerIO makes a similar conversion.
 				 * See ebus.c for details.
 				 *
-				 * Note that check_region()/request_region()
-				 * work for these devices.
+				 * Note that request_region()
+				 * works for these devices.
 				 *
 				 * XXX Neat trick, but it's a *bad* idea
 				 * to shit into regions like that.
diff --git a/drivers/char/specialix.c b/drivers/char/specialix.c
index 50e0b61..352547e 100644
--- a/drivers/char/specialix.c
+++ b/drivers/char/specialix.c
@@ -38,19 +38,19 @@
  *
  * Revision 1.0:  April 1st 1997.
  *                Initial release for alpha testing.
- * Revision 1.1:  April 14th 1997. 
- *                Incorporated Richard Hudsons suggestions, 
+ * Revision 1.1:  April 14th 1997.
+ *                Incorporated Richard Hudsons suggestions,
  *                removed some debugging printk's.
  * Revision 1.2:  April 15th 1997.
  *                Ported to 2.1.x kernels.
- * Revision 1.3:  April 17th 1997 
- *                Backported to 2.0. (Compatibility macros). 
+ * Revision 1.3:  April 17th 1997
+ *                Backported to 2.0. (Compatibility macros).
  * Revision 1.4:  April 18th 1997
- *                Fixed DTR/RTS bug that caused the card to indicate 
- *                "don't send data" to a modem after the password prompt.  
+ *                Fixed DTR/RTS bug that caused the card to indicate
+ *                "don't send data" to a modem after the password prompt.
  *                Fixed bug for premature (fake) interrupts.
  * Revision 1.5:  April 19th 1997
- *                fixed a minor typo in the header file, cleanup a little. 
+ *                fixed a minor typo in the header file, cleanup a little.
  *                performance warnings are now MAXed at once per minute.
  * Revision 1.6:  May 23 1997
  *                Changed the specialix=... format to include interrupt.
@@ -60,10 +60,10 @@
  *                port to linux-2.1.43 kernel.
  * Revision 1.9:  Oct 9  1998
  *                Added stuff for the IO8+/PCI version.
- * Revision 1.10: Oct 22  1999 / Jan 21 2000. 
- *                Added stuff for setserial. 
+ * Revision 1.10: Oct 22  1999 / Jan 21 2000.
+ *                Added stuff for setserial.
  *                Nicolas Mailhot (Nicolas.Mailhot at email.enst.fr)
- * 
+ *
  */
 
 #define VERSION "1.11"
@@ -154,7 +154,7 @@ static int sx_poll = HZ;
 
 
 
-/* 
+/*
  * The following defines are mostly for testing purposes. But if you need
  * some nice reporting in your syslog, you can define them also.
  */
@@ -188,7 +188,7 @@ static DECLARE_MUTEX(tmp_buf_sem);
 
 static unsigned long baud_table[] =  {
 	0, 50, 75, 110, 134, 150, 200, 300, 600, 1200, 1800, 2400, 4800,
-	9600, 19200, 38400, 57600, 115200, 0, 
+	9600, 19200, 38400, 57600, 115200, 0,
 };
 
 static struct specialix_board sx_board[SX_NBOARD] =  {
@@ -216,7 +216,7 @@ static inline int sx_paranoia_check(stru
 		KERN_ERR "sx: Warning: bad specialix port magic number for device %s in %s\n";
 	static const char *badinfo =
 		KERN_ERR "sx: Warning: null specialix port for device %s in %s\n";
- 
+
 	if (!port) {
 		printk(badinfo, name, routine);
 		return 1;
@@ -231,9 +231,9 @@ static inline int sx_paranoia_check(stru
 
 
 /*
- * 
+ *
  *  Service functions for specialix IO8+ driver.
- * 
+ *
  */
 
 /* Get board number from pointer */
@@ -246,7 +246,7 @@ static inline int board_No (struct speci
 /* Get port number from pointer */
 static inline int port_No (struct specialix_port const * port)
 {
-	return SX_PORT(port - sx_port); 
+	return SX_PORT(port - sx_port);
 }
 
 
@@ -309,7 +309,7 @@ static inline void sx_wait_CCR(struct sp
 			return;
 		udelay (1);
 	}
-	
+
 	printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
 }
 
@@ -329,7 +329,7 @@ static inline void sx_wait_CCR_off(struc
 			return;
 		udelay (1);
 	}
-	
+
 	printk(KERN_ERR "sx%d: Timeout waiting for CCR.\n", board_No(bp));
 }
 
@@ -338,34 +338,28 @@ static inline void sx_wait_CCR_off(struc
  *  specialix IO8+ IO range functions.
  */
 
-static inline int sx_check_io_range(struct specialix_board * bp)
+static inline int sx_request_io_range(struct specialix_board * bp)
 {
-	return check_region (bp->base, SX_IO_SPACE);
-}
-
-
-static inline void sx_request_io_range(struct specialix_board * bp)
-{
-	request_region(bp->base, 
-	               bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE,
-	               "specialix IO8+" );
+	return request_region(bp->base,
+		bp->flags & SX_BOARD_IS_PCI ? SX_PCI_IO_SPACE : SX_IO_SPACE,
+		"specialix IO8+") == NULL;
 }
 
 
 static inline void sx_release_io_range(struct specialix_board * bp)
 {
-	release_region(bp->base, 
+	release_region(bp->base,
 	               bp->flags&SX_BOARD_IS_PCI?SX_PCI_IO_SPACE:SX_IO_SPACE);
 }
 
-	
+
 /* Must be called with enabled interrupts */
-/* Ugly. Very ugly. Don't use this for anything else than initialization 
+/* Ugly. Very ugly. Don't use this for anything else than initialization
    code */
 static inline void sx_long_delay(unsigned long delay)
 {
 	unsigned long i;
-	
+
 	for (i = jiffies + delay; time_after(i, jiffies); ) ;
 }
 
@@ -378,7 +372,7 @@ static int sx_set_irq ( struct specialix
 	int i;
 	unsigned long flags;
 
-	if (bp->flags & SX_BOARD_IS_PCI) 
+	if (bp->flags & SX_BOARD_IS_PCI)
 		return 1;
 	switch (bp->irq) {
 	/* In the same order as in the docs... */
@@ -420,7 +414,7 @@ static int sx_init_CD186x(struct special
 	sx_out_off(bp, CD186x_PILR3, SX_ACK_RINT);      /* Prio for receiver intr    */
 	/* Set RegAckEn */
 	sx_out_off(bp, CD186x_SRCR, sx_in (bp, CD186x_SRCR) | SRCR_REGACKEN);
-	
+
 	/* Setting up prescaler. We need 4 ticks per 1 ms */
 	scaler =  SX_OSCFREQ/SPECIALIX_TPS;
 
@@ -448,7 +442,7 @@ static int read_cross_byte (struct speci
 	spin_lock_irqsave(&bp->lock, flags);
 	for (i=0, t=0;i<8;i++) {
 		sx_out_off (bp, CD186x_CAR, i);
-		if (sx_in_off (bp, reg) & bit) 
+		if (sx_in_off (bp, reg) & bit)
 			t |= 1 << i;
 	}
 	spin_unlock_irqrestore(&bp->lock, flags);
@@ -472,7 +466,7 @@ void missed_irq (unsigned long data)
 	spin_unlock_irqrestore(&bp->lock, flags);
 	if (irq) {
 		printk (KERN_INFO "Missed interrupt... Calling int from timer. \n");
-		sx_interrupt (((struct specialix_board *)data)->irq, 
+		sx_interrupt (((struct specialix_board *)data)->irq,
 		              (void*)data, NULL);
 	}
 	missed_irq_timer.expires = jiffies + sx_poll;
@@ -495,7 +489,7 @@ static int sx_probe(struct specialix_boa
 
 	func_enter();
 
-	if (sx_check_io_range(bp)) {
+	if (sx_request_io_range(bp)) {
 		func_exit();
 		return 1;
 	}
@@ -509,15 +503,16 @@ static int sx_probe(struct specialix_boa
 	short_pause ();
 	val2 = sx_in_off(bp, CD186x_PPRL);
 
-	
+
 	if ((val1 != 0x5a) || (val2 != 0xa5)) {
 		printk(KERN_INFO "sx%d: specialix IO8+ Board at 0x%03x not found.\n",
 		       board_No(bp), bp->base);
+		sx_release_io_range(bp);
 		func_exit();
 		return 1;
 	}
 
-	/* Check the DSR lines that Specialix uses as board 
+	/* Check the DSR lines that Specialix uses as board
 	   identification */
 	val1 = read_cross_byte (bp, CD186x_MSVR, MSVR_DSR);
 	val2 = read_cross_byte (bp, CD186x_MSVR, MSVR_RTS);
@@ -532,6 +527,7 @@ static int sx_probe(struct specialix_boa
 	if (val1 != val2) {
 		printk(KERN_INFO "sx%d: specialix IO8+ ID %02x at 0x%03x not found (%02x).\n",
 		       board_No(bp), val2, bp->base, val1);
+		sx_release_io_range(bp);
 		func_exit();
 		return 1;
 	}
@@ -546,7 +542,7 @@ static int sx_probe(struct specialix_boa
 		sx_wait_CCR(bp);
 		sx_out(bp, CD186x_CCR, CCR_TXEN);        /* Enable transmitter     */
 		sx_out(bp, CD186x_IER, IER_TXRDY);       /* Enable tx empty intr   */
-		sx_long_delay(HZ/20);	       		
+		sx_long_delay(HZ/20);
 		irqs = probe_irq_off(irqs);
 
 		dprintk (SX_DEBUG_INIT, "SRSR = %02x, ", sx_in(bp, CD186x_SRSR));
@@ -561,14 +557,15 @@ static int sx_probe(struct specialix_boa
 		}
 
 		dprintk (SX_DEBUG_INIT "val1 = %02x, val2 = %02x, val3 = %02x.\n",
-		        val1, val2, val3); 
-	
+		        val1, val2, val3);
+
 	}
-	
+
 #if 0
 	if (irqs <= 0) {
 		printk(KERN_ERR "sx%d: Can't find IRQ for specialix IO8+ board at 0x%03x.\n",
 		       board_No(bp), bp->base);
+		sx_release_io_range(bp);
 		func_exit();
 		return 1;
 	}
@@ -579,19 +576,20 @@ static int sx_probe(struct specialix_boa
 #endif
 	/* Reset CD186x again  */
 	if (!sx_init_CD186x(bp)) {
+		sx_release_io_range(bp);
 		func_exit();
-		return -EIO;
+		return 1;
 	}
 
 	sx_request_io_range(bp);
 	bp->flags |= SX_BOARD_PRESENT;
-	
+
 	/* Chip           revcode   pkgtype
 	                  GFRCR     SRCR bit 7
 	   CD180 rev B    0x81      0
 	   CD180 rev C    0x82      0
 	   CD1864 rev A   0x82      1
-	   CD1865 rev A   0x83      1  -- Do not use!!! Does not work. 
+	   CD1865 rev A   0x83      1  -- Do not use!!! Does not work.
 	   CD1865 rev B   0x84      1
 	 -- Thanks to Gwen Wang, Cirrus Logic.
 	 */
@@ -623,8 +621,8 @@ static int sx_probe(struct specialix_boa
 	return 0;
 }
 
-/* 
- * 
+/*
+ *
  *  Interrupt processing routines.
  * */
 
@@ -657,7 +655,7 @@ static inline struct specialix_port * sx
 			return port;
 		}
 	}
-	printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n", 
+	printk(KERN_INFO "sx%d: %s interrupt from invalid port %d\n",
 	       board_No(bp), what, channel);
 	return NULL;
 }
@@ -681,7 +679,7 @@ static inline void sx_receive_exc(struct
 	tty = port->tty;
 	dprintk (SX_DEBUG_RX, "port: %p count: %d BUFF_SIZE: %d\n",
 		 port,  tty->flip.count, TTY_FLIPBUF_SIZE);
-	
+
 	status = sx_in(bp, CD186x_RCSR);
 
 	dprintk (SX_DEBUG_RX, "status: 0x%x\n", status);
@@ -707,30 +705,30 @@ static inline void sx_receive_exc(struct
 		return;
 	}
 	if (status & RCSR_TOUT) {
-		printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n", 
+		printk(KERN_INFO "sx%d: port %d: Receiver timeout. Hardware problems ?\n",
 		       board_No(bp), port_No(port));
 		func_exit();
 		return;
-		
+
 	} else if (status & RCSR_BREAK) {
 		dprintk(SX_DEBUG_RX, "sx%d: port %d: Handling break...\n",
 		       board_No(bp), port_No(port));
 		*tty->flip.flag_buf_ptr++ = TTY_BREAK;
 		if (port->flags & ASYNC_SAK)
 			do_SAK(tty);
-		
-	} else if (status & RCSR_PE) 
+
+	} else if (status & RCSR_PE)
 		*tty->flip.flag_buf_ptr++ = TTY_PARITY;
-	
-	else if (status & RCSR_FE) 
+
+	else if (status & RCSR_FE)
 		*tty->flip.flag_buf_ptr++ = TTY_FRAME;
-	
+
 	else if (status & RCSR_OE)
 		*tty->flip.flag_buf_ptr++ = TTY_OVERRUN;
-	
+
 	else
 		*tty->flip.flag_buf_ptr++ = 0;
-	
+
 	*tty->flip.char_buf_ptr++ = ch;
 	tty->flip.count++;
 	schedule_delayed_work(&tty->flip.work, 1);
@@ -746,18 +744,18 @@ static inline void sx_receive(struct spe
 	unsigned char count;
 
 	func_enter();
-	
+
 	if (!(port = sx_get_port(bp, "Receive"))) {
 		dprintk (SX_DEBUG_RX, "Hmm, couldn't find port.\n");
 		func_exit();
 		return;
 	}
 	tty = port->tty;
-	
+
 	count = sx_in(bp, CD186x_RDCR);
 	dprintk (SX_DEBUG_RX, "port: %p: count: %d\n", port, count);
 	port->hits[count > 8 ? 9 : count]++;
-	
+
 	while (count--) {
 		if (tty->flip.count >= TTY_FLIPBUF_SIZE) {
 			printk(KERN_INFO "sx%d: port %d: Working around flip buffer overflow.\n",
@@ -787,7 +785,7 @@ static inline void sx_transmit(struct sp
 	}
 	dprintk (SX_DEBUG_TX, "port: %p\n", port);
 	tty = port->tty;
-	
+
 	if (port->IER & IER_TXEMPTY) {
 		/* FIFO drained */
 		sx_out(bp, CD186x_CAR, port_No(port));
@@ -796,7 +794,7 @@ static inline void sx_transmit(struct sp
 		func_exit();
 		return;
 	}
-	
+
 	if ((port->xmit_cnt <= 0 && !port->break_length)
 	    || tty->stopped || tty->hw_stopped) {
 		sx_out(bp, CD186x_CAR, port_No(port));
@@ -805,7 +803,7 @@ static inline void sx_transmit(struct sp
 		func_exit();
 		return;
 	}
-	
+
 	if (port->break_length) {
 		if (port->break_length > 0) {
 			if (port->COR2 & COR2_ETC) {
@@ -831,7 +829,7 @@ static inline void sx_transmit(struct sp
 		func_exit();
 		return;
 	}
-	
+
 	count = CD186x_NFIFO;
 	do {
 		sx_out(bp, CD186x_TDR, port->xmit_buf[port->xmit_tail++]);
@@ -839,7 +837,7 @@ static inline void sx_transmit(struct sp
 		if (--port->xmit_cnt <= 0)
 			break;
 	} while (--count > 0);
-	
+
 	if (port->xmit_cnt <= 0) {
 		sx_out(bp, CD186x_CAR, port_No(port));
 		port->IER &= ~IER_TXRDY;
@@ -862,9 +860,9 @@ static inline void sx_check_modem(struct
 	dprintk (SX_DEBUG_SIGNALS, "Modem intr. ");
 	if (!(port = sx_get_port(bp, "Modem")))
 		return;
-	
+
 	tty = port->tty;
-	
+
 	mcr = sx_in(bp, CD186x_MCR);
 	printk ("mcr = %02x.\n", mcr);
 
@@ -879,7 +877,7 @@ static inline void sx_check_modem(struct
 			schedule_work(&port->tqueue_hangup);
 		}
 	}
-	
+
 #ifdef SPECIALIX_BRAIN_DAMAGED_CTS
 	if (mcr & MCR_CTSCHG) {
 		if (sx_in(bp, CD186x_MSVR) & MSVR_CTS) {
@@ -906,7 +904,7 @@ static inline void sx_check_modem(struct
 		sx_out(bp, CD186x_IER, port->IER);
 	}
 #endif /* SPECIALIX_BRAIN_DAMAGED_CTS */
-	
+
 	/* Clear change bits */
 	sx_out(bp, CD186x_MCR, 0);
 }
@@ -940,7 +938,7 @@ static irqreturn_t sx_interrupt(int irq,
 	while ((++loop < 16) && (status = (sx_in(bp, CD186x_SRSR) &
 	                                   (SRSR_RREQint |
 		                            SRSR_TREQint |
-	                                    SRSR_MREQint)))) {	
+	                                    SRSR_MREQint)))) {
 		if (status & SRSR_RREQint) {
 			ack = sx_in(bp, CD186x_RRAR);
 
@@ -951,7 +949,7 @@ static irqreturn_t sx_interrupt(int irq,
 			else
 				printk(KERN_ERR "sx%d: status: 0x%x Bad receive ack 0x%02x.\n",
 				       board_No(bp), status, ack);
-		
+
 		} else if (status & SRSR_TREQint) {
 			ack = sx_in(bp, CD186x_TRAR);
 
@@ -963,13 +961,13 @@ static irqreturn_t sx_interrupt(int irq,
 		} else if (status & SRSR_MREQint) {
 			ack = sx_in(bp, CD186x_MRAR);
 
-			if (ack == (SX_ID | GIVR_IT_MODEM)) 
+			if (ack == (SX_ID | GIVR_IT_MODEM))
 				sx_check_modem(bp);
 			else
 				printk(KERN_ERR "sx%d: status: 0x%x Bad modem ack 0x%02x.\n",
 				       board_No(bp), status, ack);
-		
-		} 
+
+		}
 
 		sx_out(bp, CD186x_EOIR, 0);   /* Mark end of interrupt */
 	}
@@ -1026,7 +1024,7 @@ static inline int sx_setup_board(struct 
 {
 	int error;
 
-	if (bp->flags & SX_BOARD_ACTIVE) 
+	if (bp->flags & SX_BOARD_ACTIVE)
 		return 0;
 
 	if (bp->flags & SX_BOARD_IS_PCI)
@@ -1034,7 +1032,7 @@ static inline int sx_setup_board(struct 
 	else
 		error = request_irq(bp->irq, sx_interrupt, SA_INTERRUPT, "specialix IO8+", bp);
 
-	if (error) 
+	if (error)
 		return error;
 
 	turn_ints_on (bp);
@@ -1055,7 +1053,7 @@ static inline void sx_shutdown_board(str
 	}
 
 	bp->flags &= ~SX_BOARD_ACTIVE;
-	
+
 	dprintk (SX_DEBUG_IRQ, "Freeing IRQ%d for board %d.\n",
 		 bp->irq, board_No (bp));
 	free_irq(bp->irq, bp);
@@ -1068,7 +1066,7 @@ static inline void sx_shutdown_board(str
 
 
 /*
- * Setting up port characteristics. 
+ * Setting up port characteristics.
  * Must be called with disabled interrupts
  */
 static void sx_change_speed(struct specialix_board *bp, struct specialix_port *port)
@@ -1103,10 +1101,10 @@ static void sx_change_speed(struct speci
 	spin_unlock_irqrestore(&bp->lock, flags);
 	dprintk (SX_DEBUG_TERMIOS, "sx: got MSVR=%02x.\n", port->MSVR);
 	baud = C_BAUD(tty);
-	
+
 	if (baud & CBAUDEX) {
 		baud &= ~CBAUDEX;
-		if (baud < 1 || baud > 2) 
+		if (baud < 1 || baud > 2)
 			port->tty->termios->c_cflag &= ~CBAUDEX;
 		else
 			baud += 15;
@@ -1117,8 +1115,8 @@ static void sx_change_speed(struct speci
 		if ((port->flags & ASYNC_SPD_MASK) == ASYNC_SPD_VHI)
 			baud += 2;
 	}
-	
-	
+
+
 	if (!baud_table[baud]) {
 		/* Drop DTR & exit */
 		dprintk (SX_DEBUG_TERMIOS, "Dropping DTR...  Hmm....\n");
@@ -1127,7 +1125,7 @@ static void sx_change_speed(struct speci
 			spin_lock_irqsave(&bp->lock, flags);
 			sx_out(bp, CD186x_MSVR, port->MSVR );
 			spin_unlock_irqrestore(&bp->lock, flags);
-		} 
+		}
 		else
 			dprintk (SX_DEBUG_TERMIOS, "Can't drop DTR: no DTR.\n");
 		return;
@@ -1137,9 +1135,9 @@ static void sx_change_speed(struct speci
 			port ->MSVR |= MSVR_DTR;
 		}
 	}
-	
+
 	/*
-	 * Now we must calculate some speed depended things 
+	 * Now we must calculate some speed depended things
 	 */
 
 	/* Set baud rate for port */
@@ -1152,7 +1150,7 @@ static void sx_change_speed(struct speci
 		tmp = (((SX_OSCFREQ + baud_table[baud]/2) / baud_table[baud] +
 		         CD186x_TPC/2) / CD186x_TPC);
 
-	if ((tmp < 0x10) && time_before(again, jiffies)) { 
+	if ((tmp < 0x10) && time_before(again, jiffies)) {
 		again = jiffies + HZ * 60;
 		/* Page 48 of version 2.0 of the CL-CD1865 databook */
 		if (tmp >= 12) {
@@ -1164,27 +1162,27 @@ static void sx_change_speed(struct speci
 			printk (KERN_INFO "sx%d: Baud rate divisor is %ld. \n"
 			        "Warning: overstressing Cirrus chip. "
 			        "This might not work.\n"
-			        "Read specialix.txt for more info.\n", 
+			        "Read specialix.txt for more info.\n",
 			        port_No (port), tmp);
 		}
 	}
 	spin_lock_irqsave(&bp->lock, flags);
-	sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff); 
-	sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff); 
-	sx_out(bp, CD186x_RBPRL, tmp & 0xff); 
+	sx_out(bp, CD186x_RBPRH, (tmp >> 8) & 0xff);
+	sx_out(bp, CD186x_TBPRH, (tmp >> 8) & 0xff);
+	sx_out(bp, CD186x_RBPRL, tmp & 0xff);
 	sx_out(bp, CD186x_TBPRL, tmp & 0xff);
 	spin_unlock_irqrestore(&bp->lock, flags);
 	if (port->custom_divisor) {
 		baud = (SX_OSCFREQ + port->custom_divisor/2) / port->custom_divisor;
 		baud = ( baud + 5 ) / 10;
-	} else 
+	} else
 		baud = (baud_table[baud] + 5) / 10;   /* Estimated CPS */
 
 	/* Two timer ticks seems enough to wakeup something like SLIP driver */
-	tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;		
+	tmp = ((baud + HZ/2) / HZ) * 2 - CD186x_NFIFO;
 	port->wakeup_chars = (tmp < 0) ? 0 : ((tmp >= SERIAL_XMIT_SIZE) ?
 					      SERIAL_XMIT_SIZE - 1 : tmp);
-	
+
 	/* Receiver timeout will be transmission time for 1.5 chars */
 	tmp = (SPECIALIX_TPS + SPECIALIX_TPS/2 + baud/2) / baud;
 	tmp = (tmp > 0xff) ? 0xff : tmp;
@@ -1205,29 +1203,29 @@ static void sx_change_speed(struct speci
 		cor1 |= COR1_8BITS;
 		break;
 	}
-	
-	if (C_CSTOPB(tty)) 
+
+	if (C_CSTOPB(tty))
 		cor1 |= COR1_2SB;
-	
+
 	cor1 |= COR1_IGNORE;
 	if (C_PARENB(tty)) {
 		cor1 |= COR1_NORMPAR;
-		if (C_PARODD(tty)) 
+		if (C_PARODD(tty))
 			cor1 |= COR1_ODDP;
-		if (I_INPCK(tty)) 
+		if (I_INPCK(tty))
 			cor1 &= ~COR1_IGNORE;
 	}
 	/* Set marking of some errors */
 	port->mark_mask = RCSR_OE | RCSR_TOUT;
-	if (I_INPCK(tty)) 
+	if (I_INPCK(tty))
 		port->mark_mask |= RCSR_FE | RCSR_PE;
-	if (I_BRKINT(tty) || I_PARMRK(tty)) 
+	if (I_BRKINT(tty) || I_PARMRK(tty))
 		port->mark_mask |= RCSR_BREAK;
-	if (I_IGNPAR(tty)) 
+	if (I_IGNPAR(tty))
 		port->mark_mask &= ~(RCSR_FE | RCSR_PE);
 	if (I_IGNBRK(tty)) {
 		port->mark_mask &= ~RCSR_BREAK;
-		if (I_IGNPAR(tty)) 
+		if (I_IGNPAR(tty))
 			/* Real raw mode. Ignore all */
 			port->mark_mask &= ~RCSR_OE;
 	}
@@ -1241,7 +1239,7 @@ static void sx_change_speed(struct speci
 		tty->hw_stopped = !(sx_in(bp, CD186x_MSVR) & (MSVR_CTS|MSVR_DSR));
 		spin_unlock_irqrestore(&bp->lock, flags);
 #else
-		port->COR2 |= COR2_CTSAE; 
+		port->COR2 |= COR2_CTSAE;
 #endif
 	}
 	/* Enable Software Flow Control. FIXME: I'm not sure about this */
@@ -1264,11 +1262,11 @@ static void sx_change_speed(struct speci
 		mcor1 |= MCOR1_CDZD;
 		mcor2 |= MCOR2_CDOD;
 	}
-	
-	if (C_CREAD(tty)) 
+
+	if (C_CREAD(tty))
 		/* Enable receiver */
 		port->IER |= IER_RXD;
-	
+
 	/* Set input FIFO size (1-8 bytes) */
 	cor3 |= sx_rxfifo;
 	/* Setting up CD186x channel registers */
@@ -1311,11 +1309,11 @@ static int sx_setup_port(struct speciali
 		func_exit();
 		return 0;
 	}
-	
+
 	if (!port->xmit_buf) {
 		/* We may sleep in get_zeroed_page() */
 		unsigned long tmp;
-		
+
 		if (!(tmp = get_zeroed_page(GFP_KERNEL))) {
 			func_exit();
 			return -ENOMEM;
@@ -1328,10 +1326,10 @@ static int sx_setup_port(struct speciali
 		}
 		port->xmit_buf = (unsigned char *) tmp;
 	}
-		
+
 	spin_lock_irqsave(&port->lock, flags);
 
-	if (port->tty) 
+	if (port->tty)
 		clear_bit(TTY_IO_ERROR, &port->tty->flags);
 
 	port->xmit_cnt = port->xmit_head = port->xmit_tail = 0;
@@ -1340,7 +1338,7 @@ static int sx_setup_port(struct speciali
 
 	spin_unlock_irqrestore(&port->lock, flags);
 
-		
+
 	func_exit();
 	return 0;
 }
@@ -1352,14 +1350,14 @@ static void sx_shutdown_port(struct spec
 	struct tty_struct *tty;
 	int i;
 	unsigned long flags;
-	
+
 	func_enter();
 
 	if (!(port->flags & ASYNC_INITIALIZED)) {
 		func_exit();
 		return;
 	}
-	
+
 	if (sx_debug & SX_DEBUG_FIFO) {
 		dprintk(SX_DEBUG_FIFO, "sx%d: port %d: %ld overruns, FIFO hits [ ",
 			board_No(bp), port_No(port), port->overrun);
@@ -1394,13 +1392,13 @@ static void sx_shutdown_port(struct spec
 	if (tty)
 		set_bit(TTY_IO_ERROR, &tty->flags);
 	port->flags &= ~ASYNC_INITIALIZED;
-	
-	if (!bp->count) 
+
+	if (!bp->count)
 		sx_shutdown_board(bp);
 	func_exit();
 }
 
-	
+
 static int block_til_ready(struct tty_struct *tty, struct file * filp,
                            struct specialix_port *port)
 {
@@ -1427,7 +1425,7 @@ static int block_til_ready(struct tty_st
 			return -ERESTARTSYS;
 		}
 	}
-	
+
 	/*
 	 * If non-blocking mode is set, or the port is not enabled,
 	 * then make the check up front and then exit.
@@ -1477,7 +1475,7 @@ static int block_til_ready(struct tty_st
 			if (port->flags & ASYNC_HUP_NOTIFY)
 				retval = -EAGAIN;
 			else
-				retval = -ERESTARTSYS;	
+				retval = -ERESTARTSYS;
 			break;
 		}
 		if (!(port->flags & ASYNC_CLOSING) &&
@@ -1506,7 +1504,7 @@ static int block_til_ready(struct tty_st
 	port->flags |= ASYNC_NORMAL_ACTIVE;
 	func_exit();
 	return 0;
-}	
+}
 
 
 static int sx_open(struct tty_struct * tty, struct file * filp)
@@ -1526,7 +1524,7 @@ static int sx_open(struct tty_struct * t
 		func_exit();
 		return -ENODEV;
 	}
-	
+
 	bp = &sx_board[board];
 	port = sx_port + board * SX_NPORT + SX_PORT(tty->index);
 	port->overrun = 0;
@@ -1557,7 +1555,7 @@ static int sx_open(struct tty_struct * t
 		func_enter();
 		return error;
 	}
-	
+
 	if ((error = block_til_ready(tty, filp, port))) {
 		func_enter();
 		return error;
@@ -1574,7 +1572,7 @@ static void sx_close(struct tty_struct *
 	struct specialix_board *bp;
 	unsigned long flags;
 	unsigned long timeout;
-	
+
 	func_enter();
 	if (!port || sx_paranoia_check(port, tty->name, "close")) {
 		func_exit();
@@ -1587,7 +1585,7 @@ static void sx_close(struct tty_struct *
 		func_exit();
 		return;
 	}
-	
+
 	bp = port_Board(port);
 	if ((tty->count == 1) && (port->count != 1)) {
 		printk(KERN_ERR "sx%d: sx_close: bad port count;"
@@ -1607,7 +1605,7 @@ static void sx_close(struct tty_struct *
 	}
 	port->flags |= ASYNC_CLOSING;
 	/*
-	 * Now we wait for the transmit buffer to clear; and we notify 
+	 * Now we wait for the transmit buffer to clear; and we notify
 	 * the line discipline to only process XON/XOFF characters.
 	 */
 	tty->closing = 1;
@@ -1681,7 +1679,7 @@ static void sx_close(struct tty_struct *
 }
 
 
-static int sx_write(struct tty_struct * tty, 
+static int sx_write(struct tty_struct * tty,
                     const unsigned char *buf, int count)
 {
 	struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@ -1694,7 +1692,7 @@ static int sx_write(struct tty_struct * 
 		func_exit();
 		return 0;
 	}
-	
+
 	bp = port_Board(port);
 
 	if (!tty || !port->xmit_buf || !tmp_buf) {
@@ -1824,7 +1822,7 @@ static int sx_chars_in_buffer(struct tty
 	struct specialix_port *port = (struct specialix_port *)tty->driver_data;
 
 	func_enter();
-	
+
 	if (sx_paranoia_check(port, tty->name, "sx_chars_in_buffer")) {
 		func_exit();
 		return 0;
@@ -1881,13 +1879,13 @@ static int sx_tiocmget(struct tty_struct
 		port_No(port), status, sx_in (bp, CD186x_CAR));
 	dprintk (SX_DEBUG_INIT, "sx_port = %p, port = %p\n", sx_port, port);
 	if (SX_CRTSCTS(port->tty)) {
-		result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */ 
+		result  = /*   (status & MSVR_RTS) ? */ TIOCM_DTR /* : 0) */
 		          |   ((status & MSVR_DTR) ? TIOCM_RTS : 0)
 		          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
 		          |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
 		          |   ((status & MSVR_CTS) ? TIOCM_CTS : 0);
 	} else {
-		result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */ 
+		result  = /*   (status & MSVR_RTS) ? */ TIOCM_RTS /* : 0) */
 		          |   ((status & MSVR_DTR) ? TIOCM_DTR : 0)
 		          |   ((status & MSVR_CD)  ? TIOCM_CAR : 0)
 		          |/* ((status & MSVR_DSR) ? */ TIOCM_DSR /* : 0) */
@@ -1955,7 +1953,7 @@ static inline void sx_send_break(struct 
 {
 	struct specialix_board *bp = port_Board(port);
 	unsigned long flags;
-	
+
 	func_enter();
 
 	spin_lock_irqsave (&port->lock, flags);
@@ -1996,8 +1994,8 @@ static inline int sx_set_serial_info(str
 		func_enter();
 		return -EFAULT;
 	}
-	
-#if 0	
+
+#if 0
 	if ((tmp.irq != bp->irq) ||
 	    (tmp.port != bp->base) ||
 	    (tmp.type != PORT_CIRRUS) ||
@@ -2008,12 +2006,12 @@ static inline int sx_set_serial_info(str
 		func_exit();
 		return -EINVAL;
 	}
-#endif	
+#endif
 
 	change_speed = ((port->flags & ASYNC_SPD_MASK) !=
 			(tmp.flags & ASYNC_SPD_MASK));
 	change_speed |= (tmp.custom_divisor != port->custom_divisor);
-	
+
 	if (!capable(CAP_SYS_ADMIN)) {
 		if ((tmp.close_delay != port->close_delay) ||
 		    (tmp.closing_wait != port->closing_wait) ||
@@ -2045,7 +2043,7 @@ static inline int sx_get_serial_info(str
 {
 	struct serial_struct tmp;
 	struct specialix_board *bp = port_Board(port);
-	
+
 	func_enter();
 
 	/*
@@ -2074,7 +2072,7 @@ static inline int sx_get_serial_info(str
 }
 
 
-static int sx_ioctl(struct tty_struct * tty, struct file * filp, 
+static int sx_ioctl(struct tty_struct * tty, struct file * filp,
                     unsigned int cmd, unsigned long arg)
 {
 	struct specialix_port *port = (struct specialix_port *)tty->driver_data;
@@ -2087,7 +2085,7 @@ static int sx_ioctl(struct tty_struct * 
 		func_exit();
 		return -ENODEV;
 	}
-	
+
 	switch (cmd) {
 	 case TCSBRK:	/* SVID version: non-zero arg --> no break */
 		retval = tty_check_change(tty);
@@ -2129,7 +2127,7 @@ static int sx_ioctl(struct tty_struct * 
 	 case TIOCGSERIAL:
 		 func_exit();
 		return sx_get_serial_info(port, argp);
-	 case TIOCSSERIAL:	
+	 case TIOCSSERIAL:
 		 func_exit();
 		return sx_set_serial_info(port, argp);
 	 default:
@@ -2153,16 +2151,16 @@ static void sx_throttle(struct tty_struc
 		func_exit();
 		return;
 	}
-	
+
 	bp = port_Board(port);
-	
+
 	/* Use DTR instead of RTS ! */
-	if (SX_CRTSCTS (tty)) 
+	if (SX_CRTSCTS (tty))
 		port->MSVR &= ~MSVR_DTR;
 	else {
 		/* Auch!!! I think the system shouldn't call this then. */
 		/* Or maybe we're supposed (allowed?) to do our side of hw
-		   handshake anyway, even when hardware handshake is off. 
+		   handshake anyway, even when hardware handshake is off.
 		   When you see this in your logs, please report.... */
 		printk (KERN_ERR "sx%d: Need to throttle, but can't (hardware hs is off)\n",
 	                 port_No (port));
@@ -2193,14 +2191,14 @@ static void sx_unthrottle(struct tty_str
 	unsigned long flags;
 
 	func_enter();
-				
+
 	if (sx_paranoia_check(port, tty->name, "sx_unthrottle")) {
 		func_exit();
 		return;
 	}
-	
+
 	bp = port_Board(port);
-	
+
 	spin_lock_irqsave(&port->lock, flags);
 	/* XXXX Use DTR INSTEAD???? */
 	if (SX_CRTSCTS(tty)) {
@@ -2234,14 +2232,14 @@ static void sx_stop(struct tty_struct * 
 	unsigned long flags;
 
 	func_enter();
-	
+
 	if (sx_paranoia_check(port, tty->name, "sx_stop")) {
 		func_exit();
 		return;
 	}
 
 	bp = port_Board(port);
-	
+
 	spin_lock_irqsave(&port->lock, flags);
 	port->IER &= ~IER_TXRDY;
 	spin_lock_irqsave(&bp->lock, flags);
@@ -2261,14 +2259,14 @@ static void sx_start(struct tty_struct *
 	unsigned long flags;
 
 	func_enter();
-				
+
 	if (sx_paranoia_check(port, tty->name, "sx_start")) {
 		func_exit();
 		return;
 	}
-	
+
 	bp = port_Board(port);
-	
+
 	spin_lock_irqsave(&port->lock, flags);
 	if (port->xmit_cnt && port->xmit_buf && !(port->IER & IER_TXRDY)) {
 		port->IER |= IER_TXRDY;
@@ -2290,13 +2288,13 @@ static void sx_start(struct tty_struct *
  *
  * 	serial interrupt routine -> (workqueue) ->
  * 	do_sx_hangup() -> tty->hangup() -> sx_hangup()
- * 
+ *
  */
 static void do_sx_hangup(void *private_)
 {
 	struct specialix_port	*port = (struct specialix_port *) private_;
 	struct tty_struct	*tty;
-	
+
 	func_enter();
 
 	tty = port->tty;
@@ -2319,9 +2317,9 @@ static void sx_hangup(struct tty_struct 
 		func_exit();
 		return;
 	}
-	
+
 	bp = port_Board(port);
-	
+
 	sx_shutdown_port(bp, port);
 	spin_lock_irqsave(&port->lock, flags);
 	port->event = 0;
@@ -2346,10 +2344,10 @@ static void sx_set_termios(struct tty_st
 	struct specialix_port *port = (struct specialix_port *)tty->driver_data;
 	unsigned long flags;
 	struct specialix_board  * bp;
-				
+
 	if (sx_paranoia_check(port, tty->name, "sx_set_termios"))
 		return;
-	
+
 	if (tty->termios->c_cflag == old_termios->c_cflag &&
 	    tty->termios->c_iflag == old_termios->c_iflag)
 		return;
@@ -2420,7 +2418,7 @@ static int sx_init_drivers(void)
 		func_exit();
 		return 1;
 	}
-	
+
 	if (!(tmp_buf = (unsigned char *) get_zeroed_page(GFP_KERNEL))) {
 		printk(KERN_ERR "sx: Couldn't get free page.\n");
 		put_tty_driver(specialix_driver);
@@ -2457,7 +2455,7 @@ static int sx_init_drivers(void)
 		init_waitqueue_head(&sx_port[i].close_wait);
 		spin_lock_init(&sx_port[i].lock);
 	}
-	
+
 	func_exit();
 	return 0;
 }
@@ -2472,8 +2470,8 @@ static void sx_release_drivers(void)
 	func_exit();
 }
 
-/* 
- * This routine must be called by kernel at boot time 
+/*
+ * This routine must be called by kernel at boot time
  */
 static int __init specialix_init(void)
 {
@@ -2489,7 +2487,7 @@ static int __init specialix_init(void)
 #else
 	printk (KERN_INFO "sx: DTR/RTS pin is RTS when CRTSCTS is on.\n");
 #endif
-	
+
 	for (i = 0; i < SX_NBOARD; i++)
 		sx_board[i].lock = SPIN_LOCK_UNLOCKED;
 
@@ -2498,7 +2496,7 @@ static int __init specialix_init(void)
 		return -EIO;
 	}
 
-	for (i = 0; i < SX_NBOARD; i++) 
+	for (i = 0; i < SX_NBOARD; i++)
 		if (sx_board[i].base && !sx_probe(&sx_board[i]))
 			found++;
 
@@ -2512,8 +2510,8 @@ static int __init specialix_init(void)
 				i++;
 				continue;
 			}
-			pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX, 
-			                        PCI_DEVICE_ID_SPECIALIX_IO8, 
+			pdev = pci_find_device (PCI_VENDOR_ID_SPECIALIX,
+			                        PCI_DEVICE_ID_SPECIALIX_IO8,
 			                        pdev);
 			if (!pdev) break;
 
@@ -2557,10 +2555,10 @@ module_param(sx_poll, int, 0);
 /*
  * You can setup up to 4 boards.
  * by specifying "iobase=0xXXX,0xXXX ..." as insmod parameter.
- * You should specify the IRQs too in that case "irq=....,...". 
- * 
+ * You should specify the IRQs too in that case "irq=....,...".
+ *
  * More than 4 boards in one computer is not possible, as the card can
- * only use 4 different interrupts. 
+ * only use 4 different interrupts.
  *
  */
 static int __init specialix_init_module(void)
@@ -2583,16 +2581,16 @@ static int __init specialix_init_module(
 
 	return specialix_init();
 }
-	
+
 static void __exit specialix_exit_module(void)
 {
 	int i;
-	
+
 	func_enter();
 
 	sx_release_drivers();
 	for (i = 0; i < SX_NBOARD; i++)
-		if (sx_board[i].flags & SX_BOARD_PRESENT) 
+		if (sx_board[i].flags & SX_BOARD_PRESENT)
 			sx_release_io_range(&sx_board[i]);
 #ifdef SPECIALIX_TIMER
 	del_timer (&missed_irq_timer);
diff --git a/drivers/net/eepro.c b/drivers/net/eepro.c
index 1ce2c67..a806dfe 100644
--- a/drivers/net/eepro.c
+++ b/drivers/net/eepro.c
@@ -552,8 +552,7 @@ static int __init do_eepro_probe(struct 
 	{
 		unsigned short int WS[32]=WakeupSeq;
 
-		if (check_region(WakeupPort, 2)==0) {
-
+		if (request_region(WakeupPort, 2, "eepro wakeup")) {
 			if (net_debug>5)
 				printk(KERN_DEBUG "Waking UP\n");
 
@@ -563,7 +562,10 @@ static int __init do_eepro_probe(struct 
 				outb_p(WS[i],WakeupPort);
 				if (net_debug>5) printk(KERN_DEBUG ": %#x ",WS[i]);
 			}
-		} else printk(KERN_WARNING "Checkregion Failed!\n");
+
+			release_region(WakeupPort, 2);
+		} else
+			printk(KERN_WARNING "PnP wakeup region busy!\n");
 	}
 #endif
 
@@ -705,7 +707,7 @@ static void __init eepro_print_info (str
 					dev->name, (unsigned)dev->base_addr);
 			break;
 		case LAN595FX:
-			printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,", 
+			printk("%s: Intel EtherExpress Pro/10+ ISA\n at %#x,",
 					dev->name, (unsigned)dev->base_addr);
 			break;
 		case LAN595TX:
@@ -713,7 +715,7 @@ static void __init eepro_print_info (str
 					dev->name, (unsigned)dev->base_addr);
 			break;
 		case LAN595:
-			printk("%s: Intel 82595-based lan card at %#x,", 
+			printk("%s: Intel 82595-based lan card at %#x,",
 					dev->name, (unsigned)dev->base_addr);
 	}
 
@@ -726,7 +728,7 @@ static void __init eepro_print_info (str
 
 	if (dev->irq > 2)
 		printk(", IRQ %d, %s.\n", dev->irq, ifmap[dev->if_port]);
-	else 
+	else
 		printk(", %s.\n", ifmap[dev->if_port]);
 
 	if (net_debug > 3) {
@@ -756,7 +758,7 @@ static int __init eepro_probe1(struct ne
 	int err;
 
 	/* Grab the region so we can find another board if autoIRQ fails. */
-	if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) { 
+	if (!request_region(ioaddr, EEPRO_IO_EXTENT, DRV_NAME)) {
 		if (!autoprobe)
 			printk(KERN_WARNING "EEPRO: io-port 0x%04x in use \n",
 				ioaddr);
@@ -838,15 +840,15 @@ static int __init eepro_probe1(struct ne
  		/* Mask off INT number */
  		int count = lp->word[1] & 7;
  		unsigned irqMask = lp->word[7];
- 
+
  		while (count--)
  			irqMask &= irqMask - 1;
- 
+
  		count = ffs(irqMask);
- 
+
  		if (count)
  			dev->irq = count - 1;
- 
+
  		if (dev->irq < 2) {
  			printk(KERN_ERR " Duh! illegal interrupt vector stored in EEPROM.\n");
  			goto exit;
@@ -854,7 +856,7 @@ static int __init eepro_probe1(struct ne
  			dev->irq = 9;
  		}
  	}
- 
+
  	dev->open               = eepro_open;
  	dev->stop               = eepro_close;
  	dev->hard_start_xmit    = eepro_send_packet;
@@ -863,7 +865,7 @@ static int __init eepro_probe1(struct ne
  	dev->tx_timeout		= eepro_tx_timeout;
  	dev->watchdog_timeo	= TX_TIMEOUT;
 	dev->ethtool_ops	= &eepro_ethtool_ops;
- 
+
 	/* print boot time info */
 	eepro_print_info(dev);
 
@@ -1047,8 +1049,8 @@ static int eepro_open(struct net_device 
 
 
 	/* Initialize the RCV and XMT upper and lower limits */
-	outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG); 
-	outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG); 
+	outb(lp->rcv_lower_limit >> 8, ioaddr + RCV_LOWER_LIMIT_REG);
+	outb(lp->rcv_upper_limit >> 8, ioaddr + RCV_UPPER_LIMIT_REG);
 	outb(lp->xmt_lower_limit >> 8, ioaddr + lp->xmt_lower_limit_reg);
 	outb(lp->xmt_upper_limit >> 8, ioaddr + lp->xmt_upper_limit_reg);
 
@@ -1065,12 +1067,12 @@ static int eepro_open(struct net_device 
 	eepro_clear_int(ioaddr);
 
 	/* Initialize RCV */
-	outw(lp->rcv_lower_limit, ioaddr + RCV_BAR); 
+	outw(lp->rcv_lower_limit, ioaddr + RCV_BAR);
 	lp->rx_start = lp->rcv_lower_limit;
-	outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP); 
+	outw(lp->rcv_upper_limit | 0xfe, ioaddr + RCV_STOP);
 
 	/* Initialize XMT */
-	outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar); 
+	outw(lp->xmt_lower_limit, ioaddr + lp->xmt_bar);
 	lp->tx_start = lp->tx_end = lp->xmt_lower_limit;
 	lp->tx_last = 0;
 
@@ -1411,7 +1413,7 @@ set_multicast_list(struct net_device *de
 				outb(0x08, ioaddr + STATUS_REG);
 
 				if (i & 0x20) { /* command ABORTed */
-					printk(KERN_NOTICE "%s: multicast setup failed.\n", 
+					printk(KERN_NOTICE "%s: multicast setup failed.\n",
 						dev->name);
 					break;
 				} else if ((i & 0x0f) == 0x03)	{ /* MC-Done */
@@ -1512,7 +1514,7 @@ hardware_send_packet(struct net_device *
 		end = last + (((length + 3) >> 1) << 1) + XMT_HEADER;
 
 	if (end >= lp->xmt_upper_limit + 2) { /* the transmit buffer is wrapped around */
-		if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {	
+		if ((lp->xmt_upper_limit + 2 - last) <= XMT_HEADER) {
 				/* Arrrr!!!, must keep the xmt header together,
 				several days were lost to chase this one down. */
 			last = lp->xmt_lower_limit;
@@ -1643,7 +1645,7 @@ eepro_rx(struct net_device *dev)
 			else if (rcv_status & 0x0800)
 				lp->stats.rx_crc_errors++;
 
-			printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n", 
+			printk(KERN_DEBUG "%s: event = %#x, status = %#x, next = %#x, size = %#x\n",
 				dev->name, rcv_event, rcv_status, rcv_next_frame, rcv_size);
 		}
 
@@ -1674,10 +1676,10 @@ eepro_transmit_interrupt(struct net_devi
 {
 	struct eepro_local *lp = netdev_priv(dev);
 	short ioaddr = dev->base_addr;
-	short boguscount = 25; 
+	short boguscount = 25;
 	short xmt_status;
 
-	while ((lp->tx_start != lp->tx_end) && boguscount--) { 
+	while ((lp->tx_start != lp->tx_end) && boguscount--) {
 
 		outw(lp->tx_start, ioaddr + HOST_ADDRESS_REG);
 		xmt_status = inw(ioaddr+IO_PORT);
@@ -1723,7 +1725,7 @@ static int eepro_ethtool_get_settings(st
 {
 	struct eepro_local	*lp = (struct eepro_local *)dev->priv;
 
-	cmd->supported = 	SUPPORTED_10baseT_Half | 
+	cmd->supported = 	SUPPORTED_10baseT_Half |
 				SUPPORTED_10baseT_Full |
 				SUPPORTED_Autoneg;
 	cmd->advertising =	ADVERTISED_10baseT_Half |
diff --git a/include/asm-m68k/sun3xflop.h b/include/asm-m68k/sun3xflop.h
index 1ed3b78..fda1ecc 100644
--- a/include/asm-m68k/sun3xflop.h
+++ b/include/asm-m68k/sun3xflop.h
@@ -27,10 +27,8 @@
 
 /* We don't need no stinkin' I/O port allocation crap. */
 #undef release_region
-#undef check_region
 #undef request_region
 #define release_region(X, Y)	do { } while(0)
-#define check_region(X, Y)	(0)
 #define request_region(X, Y, Z)	(1)
 
 struct sun3xflop_private {
diff --git a/include/asm-m68knommu/ide.h b/include/asm-m68knommu/ide.h
index b1cbf8b..836f072 100644
--- a/include/asm-m68knommu/ide.h
+++ b/include/asm-m68knommu/ide.h
@@ -163,13 +163,6 @@ ide_free_irq(unsigned int irq, void *dev
 }
 
 
-static IDE_INLINE int
-ide_check_region(ide_ioreg_t from, unsigned int extent)
-{
-	return 0;
-}
-
-
 static IDE_INLINE void
 ide_request_region(ide_ioreg_t from, unsigned int extent, const char *name)
 {
diff --git a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h
index 3243cf2..b27bf7a 100644
--- a/include/asm-parisc/ide.h
+++ b/include/asm-parisc/ide.h
@@ -22,7 +22,6 @@
 
 #define ide_request_irq(irq,hand,flg,dev,id)	request_irq((irq),(hand),(flg),(dev),(id))
 #define ide_free_irq(irq,dev_id)		free_irq((irq), (dev_id))
-#define ide_check_region(from,extent)		check_region((from), (extent))
 #define ide_request_region(from,extent,name)	request_region((from), (extent), (name))
 #define ide_release_region(from,extent)		release_region((from), (extent))
 /* Generic I/O and MEMIO string operations.  */
diff --git a/include/asm-sparc/floppy.h b/include/asm-sparc/floppy.h
index caf9261..7a941b8 100644
--- a/include/asm-sparc/floppy.h
+++ b/include/asm-sparc/floppy.h
@@ -17,10 +17,8 @@
 
 /* We don't need no stinkin' I/O port allocation crap. */
 #undef release_region
-#undef check_region
 #undef request_region
 #define release_region(X, Y)	do { } while(0)
-#define check_region(X, Y)	(0)
 #define request_region(X, Y, Z)	(1)
 
 /* References:
diff --git a/sound/oss/cs4232.c b/sound/oss/cs4232.c
index 6ec308f..7c59e2d 100644
--- a/sound/oss/cs4232.c
+++ b/sound/oss/cs4232.c
@@ -195,10 +195,12 @@ static int __init probe_cs4232(struct ad
 		CS_OUT2(0x15, 0x00);	/* Select logical device 0 (WSS/SB/FM) */
 		CS_OUT3(0x47, (base >> 8) & 0xff, base & 0xff);	/* WSS base */
 
-		if (check_region(0x388, 4))	/* Not free */
+		if (!request_region(0x388, 4, "FM"))	/* Not free */
 			CS_OUT3(0x48, 0x00, 0x00)	/* FM base off */
-		else
+		else {
+			release_region(0x388, 4);
 			CS_OUT3(0x48, 0x03, 0x88);	/* FM base 0x388 */
+		}
 
 		CS_OUT3(0x42, 0x00, 0x00);	/* SB base off */
 		CS_OUT2(0x22, irq);		/* SB+WSS IRQ */
diff --git a/sound/oss/wavfront.c b/sound/oss/wavfront.c
index b92ba89..b1a4eeb 100644
--- a/sound/oss/wavfront.c
+++ b/sound/oss/wavfront.c
@@ -2434,7 +2434,7 @@ static int __init detect_wavefront (int 
 	   consumes 16.
 	*/
 
-	if (check_region (io_base, 16)) {
+	if (!request_region (io_base, 16, "wavfront")) {
 		printk (KERN_ERR LOGNAME "IO address range 0x%x - 0x%x "
 			"already in use - ignored\n", dev.base,
 			dev.base+15);
@@ -2466,10 +2466,13 @@ static int __init detect_wavefront (int 
 		} else {
 			printk (KERN_WARNING LOGNAME "not raw, but no "
 				"hardware version!\n");
+			release_region (io_base, 16);
 			return 0;
 		}
 
 		if (!wf_raw) {
+			/* will re-acquire region in install_wavefront() */
+			release_region (io_base, 16);
 			return 1;
 		} else {
 			printk (KERN_INFO LOGNAME
@@ -2489,6 +2492,7 @@ static int __init detect_wavefront (int 
 
 	if (wavefront_hw_reset ()) {
 		printk (KERN_WARNING LOGNAME "hardware reset failed\n");
+		release_region (io_base, 16);
 		return 0;
 	}
 
@@ -2496,6 +2500,8 @@ static int __init detect_wavefront (int 
 
 	dev.has_fx = (detect_wffx () == 0);
 
+	/* will re-acquire region in install_wavefront() */
+	release_region (io_base, 16);
 	return 1;
 }
 
@@ -2804,17 +2810,27 @@ static int __init wavefront_init (int at
 }
 
 static int __init install_wavefront (void)
-
 {
+	if (!request_region (dev.base+2, 6, "wavefront synth"))
+		return -1;
+
+	if (dev.has_fx) {
+		if (!request_region (dev.base+8, 8, "wavefront fx")) {
+			release_region (dev.base+2, 6);
+			return -1;
+		}
+	}
+
 	if ((dev.synth_dev = register_sound_synth (&wavefront_fops, -1)) < 0) {
 		printk (KERN_ERR LOGNAME "cannot register raw synth\n");
-		return -1;
+		goto err_out;
 	}
 
 #if OSS_SUPPORT_LEVEL & OSS_SUPPORT_SEQ
 	if ((dev.oss_dev = sound_alloc_synthdev()) == -1) {
 		printk (KERN_ERR LOGNAME "Too many sequencers\n");
-		return -1;
+		/* FIXME: leak: should unregister sound synth */
+		goto err_out;
 	} else {
 		synth_devs[dev.oss_dev] = &wavefront_operations;
 	}
@@ -2827,20 +2843,20 @@ static int __init install_wavefront (voi
 		sound_unload_synthdev (dev.oss_dev);
 #endif /* OSS_SUPPORT_SEQ */ 
 
-		return -1;
+		goto err_out;
 	}
     
-	request_region (dev.base+2, 6, "wavefront synth");
-
-	if (dev.has_fx) {
-		request_region (dev.base+8, 8, "wavefront fx");
-	}
-
 	if (wavefront_config_midi ()) {
 		printk (KERN_WARNING LOGNAME "could not initialize MIDI.\n");
 	}
 
 	return dev.oss_dev;
+
+err_out:
+	release_region (dev.base+2, 6);
+	if (dev.has_fx)
+		release_region (dev.base+8, 8);
+	return -1;
 }
 
 static void __exit uninstall_wavefront (void)
---
0.99.8.GIT


--- NEW FILE 1943-Typo-fix-dot-after-newline-in-printk-strings.txt ---
Subject: [PATCH] Typo fix: dot after newline in printk strings
From: Jean Delvare <khali at linux-fr.org>
Date: 1130713343 -0800

Typo fix: dots appearing after a newline in printk strings.

Signed-off-by: Jean Delvare <khali at linux-fr.org>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/char/ser_a2232.c                  |    2 +-
 drivers/message/i2o/debug.c               |    2 +-
 drivers/net/wireless/prism54/islpci_mgt.c |    2 +-
 drivers/pci/hotplug/ibmphp_core.c         |    2 +-
 drivers/usb/input/pid.c                   |    2 +-
 net/ipv4/netfilter/ipt_addrtype.c         |    2 +-
 sound/oss/awe_wave.c                      |    2 +-
 7 files changed, 7 insertions(+), 7 deletions(-)

applies-to: fdc8a61c73257dcf8866cf7b9213ce78d2422e7f
3fa63c7d82ab9a12a5d0a299069f8df9f35aa011
diff --git a/drivers/char/ser_a2232.c b/drivers/char/ser_a2232.c
index 6b4e9d1..dda30e4 100644
--- a/drivers/char/ser_a2232.c
+++ b/drivers/char/ser_a2232.c
@@ -790,7 +790,7 @@ static int __init a2232board_init(void)
 
 	}	
 
-	printk("Total: %d A2232 boards initialized.\n.", nr_a2232); /* Some status report if no card was found */
+	printk("Total: %d A2232 boards initialized.\n", nr_a2232); /* Some status report if no card was found */
 
 	a2232_init_portstructs();
 
diff --git a/drivers/message/i2o/debug.c b/drivers/message/i2o/debug.c
index 018ca88..40d4ea8 100644
--- a/drivers/message/i2o/debug.c
+++ b/drivers/message/i2o/debug.c
@@ -90,7 +90,7 @@ static void i2o_report_fail_status(u8 re
 	};
 
 	if (req_status == I2O_FSC_TRANSPORT_UNKNOWN_FAILURE)
-		printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x)\n.",
+		printk(KERN_DEBUG "TRANSPORT_UNKNOWN_FAILURE (%0#2x).\n",
 		       req_status);
 	else
 		printk(KERN_DEBUG "TRANSPORT_%s.\n",
diff --git a/drivers/net/wireless/prism54/islpci_mgt.c b/drivers/net/wireless/prism54/islpci_mgt.c
index 4937a5a..6a60c59 100644
--- a/drivers/net/wireless/prism54/islpci_mgt.c
+++ b/drivers/net/wireless/prism54/islpci_mgt.c
@@ -137,7 +137,7 @@ islpci_mgmt_rx_fill(struct net_device *n
 						       PCI_DMA_FROMDEVICE);
 			if (!buf->pci_addr) {
 				printk(KERN_WARNING
-				       "Failed to make memory DMA'able\n.");
+				       "Failed to make memory DMA'able.\n");
 				return -ENOMEM;
 			}
 		}
diff --git a/drivers/pci/hotplug/ibmphp_core.c b/drivers/pci/hotplug/ibmphp_core.c
index 0392e00..aabf1e7 100644
--- a/drivers/pci/hotplug/ibmphp_core.c
+++ b/drivers/pci/hotplug/ibmphp_core.c
@@ -1077,7 +1077,7 @@ static int enable_slot(struct hotplug_sl
 	if (rc) {
 		err("Adding this card exceeds the limitations of this bus.\n");
 		err("(i.e., >1 133MHz cards running on same bus, or "
-		     ">2 66 PCI cards running on same bus\n.");
+		     ">2 66 PCI cards running on same bus.\n");
 		err("Try hot-adding into another bus\n");
 		rc = -EINVAL;
 		goto error_nopower;
diff --git a/drivers/usb/input/pid.c b/drivers/usb/input/pid.c
index a00672c..dca5ee9 100644
--- a/drivers/usb/input/pid.c
+++ b/drivers/usb/input/pid.c
@@ -198,7 +198,7 @@ static int hid_pid_upload_effect(struct 
 		}
 
 		effect->id = id;
-		dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d\n.", id);
+		dev_dbg(&pid_private->hid->dev->dev, "effect ID is %d.\n", id);
 		pid_private->effects[id].owner = current->pid;
 		pid_private->effects[id].flags = (1 << FF_PID_FLAGS_USED);
 		spin_unlock_irqrestore(&pid_private->lock, flags);
diff --git a/net/ipv4/netfilter/ipt_addrtype.c b/net/ipv4/netfilter/ipt_addrtype.c
index f5909a4..e19c2a5 100644
--- a/net/ipv4/netfilter/ipt_addrtype.c
+++ b/net/ipv4/netfilter/ipt_addrtype.c
@@ -48,7 +48,7 @@ static int checkentry(const char *tablen
 		      unsigned int hook_mask)
 {
 	if (matchsize != IPT_ALIGN(sizeof(struct ipt_addrtype_info))) {
-		printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n.",
+		printk(KERN_ERR "ipt_addrtype: invalid size (%u != %Zu)\n",
 		       matchsize, IPT_ALIGN(sizeof(struct ipt_addrtype_info)));
 		return 0;
 	}
diff --git a/sound/oss/awe_wave.c b/sound/oss/awe_wave.c
index d2b9bed..b3ea719 100644
--- a/sound/oss/awe_wave.c
+++ b/sound/oss/awe_wave.c
@@ -6062,7 +6062,7 @@ static int awe_pnp_probe(struct pnp_dev 
 	io1 = pnp_port_start(dev,0);
 	io2 = pnp_port_start(dev,1);
 	io3 = pnp_port_start(dev,2);
-	printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x\n.",
+	printk(KERN_INFO "AWE32: A PnP Wave Table was detected at IO's %#x,%#x,%#x.\n",
 	       io1, io2, io3);
 	setup_ports(io1, io2, io3);
 
---
0.99.8.GIT


--- NEW FILE 2008-sparse-cleanups-NULL-pointers-C99-struct-init.txt ---
Subject: [PATCH] sparse cleanups: NULL pointers, C99 struct init.
From: Randy Dunlap <rdunlap at xenotime.net>
Date: 1130713409 -0800

Convert most of the remaining "Using plain integer as NULL pointer" sparse
warnings to use NULL.  (Not duplicating patches that are already in -mm,
-bird, or -kj.)

Convert isdn driver struct initializer to use C99 syntax.

Signed-off-by: Randy Dunlap <rdunlap at xenotime.net>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 arch/i386/kernel/reboot_fixups.c    |    2 +-
 drivers/char/tpm/tpm_atmel.c        |    2 +-
 drivers/char/tpm/tpm_nsc.c          |    2 +-
 drivers/isdn/hisax/hfc4s8s_l1.c     |   10 +++++-----
 drivers/media/dvb/dvb-usb/dtt200u.c |    4 ++--
 drivers/media/dvb/dvb-usb/vp7045.c  |    2 +-
 drivers/net/skfp/smt.c              |    2 +-
 7 files changed, 12 insertions(+), 12 deletions(-)

applies-to: 31d43ab177ef00fbef3d15c9513ba737029b6d48
874ec33ff9ccf3651590697a2c2923b911bf31d0
diff --git a/arch/i386/kernel/reboot_fixups.c b/arch/i386/kernel/reboot_fixups.c
index 1b183b3..c9b8733 100644
--- a/arch/i386/kernel/reboot_fixups.c
+++ b/arch/i386/kernel/reboot_fixups.c
@@ -44,7 +44,7 @@ void mach_reboot_fixups(void)
 
 	for (i=0; i < (sizeof(fixups_table)/sizeof(fixups_table[0])); i++) {
 		cur = &(fixups_table[i]);
-		dev = pci_get_device(cur->vendor, cur->device, 0);
+		dev = pci_get_device(cur->vendor, cur->device, NULL);
 		if (!dev)
 			continue;
 
diff --git a/drivers/char/tpm/tpm_atmel.c b/drivers/char/tpm/tpm_atmel.c
index d12ac1a..8cb42e8 100644
--- a/drivers/char/tpm/tpm_atmel.c
+++ b/drivers/char/tpm/tpm_atmel.c
@@ -142,7 +142,7 @@ static struct attribute* atmel_attrs[] =
 	&dev_attr_pcrs.attr,
 	&dev_attr_caps.attr,
 	&dev_attr_cancel.attr,
-	0,
+	NULL,
 };
 
 static struct attribute_group atmel_attr_grp = { .attrs = atmel_attrs };
diff --git a/drivers/char/tpm/tpm_nsc.c b/drivers/char/tpm/tpm_nsc.c
index 6adfc07..253871b 100644
--- a/drivers/char/tpm/tpm_nsc.c
+++ b/drivers/char/tpm/tpm_nsc.c
@@ -244,7 +244,7 @@ static struct attribute * nsc_attrs[] = 
 	&dev_attr_pcrs.attr,
 	&dev_attr_caps.attr,
 	&dev_attr_cancel.attr,
-	0,
+	NULL,
 };
 
 static struct attribute_group nsc_attr_grp = { .attrs = nsc_attrs };
diff --git a/drivers/isdn/hisax/hfc4s8s_l1.c b/drivers/isdn/hisax/hfc4s8s_l1.c
index 7333377..e3866b0 100644
--- a/drivers/isdn/hisax/hfc4s8s_l1.c
+++ b/drivers/isdn/hisax/hfc4s8s_l1.c
@@ -1063,7 +1063,7 @@ tx_b_frame(struct hfc4s8s_btype *bch)
 				Write_hfc8(l1->hw, A_INC_RES_FIFO, 1);
 			}
 			ack_len += skb->truesize;
-			bch->tx_skb = 0;
+			bch->tx_skb = NULL;
 			bch->tx_cnt = 0;
 			dev_kfree_skb(skb);
 		} else
@@ -1659,10 +1659,10 @@ hfc4s8s_remove(struct pci_dev *pdev)
 }
 
 static struct pci_driver hfc4s8s_driver = {
-      name:"hfc4s8s_l1",
-      probe:hfc4s8s_probe,
-      remove:__devexit_p(hfc4s8s_remove),
-      id_table:hfc4s8s_ids,
+      .name	= "hfc4s8s_l1",
+      .probe	= hfc4s8s_probe,
+      .remove	= __devexit_p(hfc4s8s_remove),
+      .id_table	= hfc4s8s_ids,
 };
 
 /**********************/
diff --git a/drivers/media/dvb/dvb-usb/dtt200u.c b/drivers/media/dvb/dvb-usb/dtt200u.c
index 5aa12eb..b595476 100644
--- a/drivers/media/dvb/dvb-usb/dtt200u.c
+++ b/drivers/media/dvb/dvb-usb/dtt200u.c
@@ -151,7 +151,7 @@ static struct dvb_usb_properties dtt200u
 		  .cold_ids = { &dtt200u_usb_table[0], NULL },
 		  .warm_ids = { &dtt200u_usb_table[1], NULL },
 		},
-		{ 0 },
+		{ NULL },
 	}
 };
 
@@ -192,7 +192,7 @@ static struct dvb_usb_properties wt220u_
 		  .cold_ids = { &dtt200u_usb_table[2], NULL },
 		  .warm_ids = { &dtt200u_usb_table[3], NULL },
 		},
-		{ 0 },
+		{ NULL },
 	}
 };
 
diff --git a/drivers/media/dvb/dvb-usb/vp7045.c b/drivers/media/dvb/dvb-usb/vp7045.c
index 0f57abe..75765e3 100644
--- a/drivers/media/dvb/dvb-usb/vp7045.c
+++ b/drivers/media/dvb/dvb-usb/vp7045.c
@@ -247,7 +247,7 @@ static struct dvb_usb_properties vp7045_
 		  .cold_ids = { &vp7045_usb_table[2], NULL },
 		  .warm_ids = { &vp7045_usb_table[3], NULL },
 		},
-		{ 0 },
+		{ NULL },
 	}
 };
 
diff --git a/drivers/net/skfp/smt.c b/drivers/net/skfp/smt.c
index f17c05c..99a776a 100644
--- a/drivers/net/skfp/smt.c
+++ b/drivers/net/skfp/smt.c
@@ -1896,7 +1896,7 @@ void smt_swap_para(struct smt_header *sm
 
 static void smt_string_swap(char *data, const char *format, int len)
 {
-	const char	*open_paren = 0 ;
+	const char	*open_paren = NULL ;
 	int	x ;
 
 	while (len > 0  && *format) {
---
0.99.8.GIT


--- NEW FILE 2207-ibmveth-fix-panic-in-initial-replenish-cycle.txt ---
Subject: [PATCH] ibmveth fix panic in initial replenish cycle
From: Santiago Leon <santil at us.ibm.com>
Date: 1130872509 -0500

This patch fixes a panic in the current tree caused by a race condition between the initial replenish cycle and the rx processing of the first packets trying to replenish the buffers.

Signed-off-by: Santiago Leon <santil at us.ibm.com>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/ibmveth.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: dfb817ef7e643a47a2b17309374a4647159fc8df
6c2af71f7f6ac10ab45e9461e1dd7aa09079643a
diff --git a/drivers/net/ibmveth.c b/drivers/net/ibmveth.c
index e5246f2..94239f6 100644
--- a/drivers/net/ibmveth.c
+++ b/drivers/net/ibmveth.c
@@ -535,7 +535,7 @@ static int ibmveth_open(struct net_devic
 	}
 
 	ibmveth_debug_printk("initial replenish cycle\n");
-	ibmveth_replenish_task(adapter);
+	ibmveth_interrupt(netdev->irq, netdev, NULL);
 
 	netif_start_queue(netdev);
 
---
0.99.8.GIT


--- NEW FILE 2409-drivers-net-wireless-airo.c-unsigned-comparason.txt ---
Subject: [PATCH] drivers/net/wireless/airo.c unsigned comparason
From: Gabriel A. Devenyi <ace at staticwave.ca>
Date: 1131064247 -0500

fid is declared as a u32 (unsigned int), and then a few lines later, it is checked for a value < 0, which is clearly useless.
In the two locations this function is used, in one it is *explicitly* given a negative number, which would be ignored with the
current definition.

Thanks to LinuxICC (http://linuxicc.sf.net).

Signed-off-by: Gabriel A. Devenyi <ace at staticwave.ca>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/wireless/airo.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 9936112bd195bfbaacc9a75f2ea7ff757a2c0546
29b09fcc341ede8dc08c900b132903fdd0231400
diff --git a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
index 750c016..849ac88 100644
--- a/drivers/net/wireless/airo.c
+++ b/drivers/net/wireless/airo.c
@@ -2040,7 +2040,7 @@ static int mpi_send_packet (struct net_d
 	return 1;
 }
 
-static void get_tx_error(struct airo_info *ai, u32 fid)
+static void get_tx_error(struct airo_info *ai, s32 fid)
 {
 	u16 status;
 
---
0.99.8.GIT


--- NEW FILE 2410-S2io-Multi-buffer-mode-support.txt ---
Subject: [PATCH] S2io: Multi buffer mode support
From: Ananda Raju <Ananda.Raju at neterion.com>
Date: 1130795731 -0500

Hi,
This patch  provides dynamic two buffer-mode and 3 buffer-mode options.
Previously 2 buffer-mode was compilation option. Now with this patch applied
one can load driver in 2 buffer-mode with module-load parameter

ie.
#insmod s2io.ko rx_ring_mode=2

This patch also provides 3 buffer-mode which provides header separation
functionality. In 3 buffer-mode skb->data will have L2/L3/L4 headers and
"skb_shinfo(skb)->frag_list->data" will have have L4 payload.
one can load driver in 3 buffer-mode with same above module-load parameter

ie.
#insmod s2io.ko rx_ring_mode=3

Please review the patch.

Signed-off-by: Ananda Raju <ananda.raju at neterion.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/Kconfig |   11 -
 drivers/net/s2io.c  |  762 +++++++++++++++++++++++++++------------------------
 drivers/net/s2io.h  |   91 +++---
 3 files changed, 455 insertions(+), 409 deletions(-)

applies-to: e3a5ea7d07e60b81055c364d5bcbca8579557496
da6971d8ece2ec9762509e20dda6808335b5a10b
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index bb3bda3..1958d9e 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2258,17 +2258,6 @@ config S2IO_NAPI
 
 	  If in doubt, say N.
 
-config 2BUFF_MODE
-	bool "Use 2 Buffer Mode on Rx side."
-	depends on S2IO
-	---help---
-	On enabling the 2 buffer mode, the received frame will be
-	split into 2 parts before being DMA'ed to the hosts memory.
-	The parts are the ethernet header and ethernet payload. 
-	This is useful on systems where DMA'ing to to unaligned 
-	physical memory loactions comes with a heavy price.
-	If not sure please say N.
-
 endmenu
 
 if !UML
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 3f5e93a..9c49354 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -30,6 +30,8 @@
  * in the driver.
  * rx_ring_sz: This defines the number of descriptors each ring can have. This
  * is also an array of size 8.
+ * rx_ring_mode: This defines the operation mode of all 8 rings. The valid
+ *		values are 1, 2 and 3.
  * tx_fifo_num: This defines the number of Tx FIFOs thats used int the driver.
  * tx_fifo_len: This too is an array of 8. Each element defines the number of
  * Tx descriptors that can be associated with each corresponding FIFO.
@@ -65,12 +67,15 @@
 #include "s2io.h"
 #include "s2io-regs.h"
 
-#define DRV_VERSION "Version 2.0.9.1"
+#define DRV_VERSION "Version 2.0.9.3"
 
 /* S2io Driver name & version. */
 static char s2io_driver_name[] = "Neterion";
 static char s2io_driver_version[] = DRV_VERSION;
 
+int rxd_size[4] = {32,48,48,64};
+int rxd_count[4] = {127,85,85,63};
+
 static inline int RXD_IS_UP2DT(RxD_t *rxdp)
 {
 	int ret;
@@ -104,7 +109,7 @@ static inline int rx_buffer_level(nic_t 
 	mac_control = &sp->mac_control;
 	if ((mac_control->rings[ring].pkt_cnt - rxb_size) > 16) {
 		level = LOW;
-		if (rxb_size <= MAX_RXDS_PER_BLOCK) {
+		if (rxb_size <= rxd_count[sp->rxd_mode]) {
 			level = PANIC;
 		}
 	}
@@ -296,6 +301,7 @@ static unsigned int rx_ring_sz[MAX_RX_RI
     {[0 ...(MAX_RX_RINGS - 1)] = 0 };
 static unsigned int rts_frm_len[MAX_RX_RINGS] =
     {[0 ...(MAX_RX_RINGS - 1)] = 0 };
+static unsigned int rx_ring_mode = 1;
 static unsigned int use_continuous_tx_intrs = 1;
 static unsigned int rmac_pause_time = 65535;
 static unsigned int mc_pause_threshold_q0q3 = 187;
@@ -304,6 +310,7 @@ static unsigned int shared_splits;
 static unsigned int tmac_util_period = 5;
 static unsigned int rmac_util_period = 5;
 static unsigned int bimodal = 0;
+static unsigned int l3l4hdr_size = 128;
 #ifndef CONFIG_S2IO_NAPI
 static unsigned int indicate_max_pkts;
 #endif
@@ -357,10 +364,8 @@ static int init_shared_mem(struct s2io_n
 	int i, j, blk_cnt, rx_sz, tx_sz;
 	int lst_size, lst_per_page;
 	struct net_device *dev = nic->dev;
-#ifdef CONFIG_2BUFF_MODE
 	unsigned long tmp;
 	buffAdd_t *ba;
-#endif
 
 	mac_info_t *mac_control;
 	struct config_param *config;
@@ -458,7 +463,8 @@ static int init_shared_mem(struct s2io_n
 	/* Allocation and initialization of RXDs in Rings */
 	size = 0;
 	for (i = 0; i < config->rx_ring_num; i++) {
-		if (config->rx_cfg[i].num_rxd % (MAX_RXDS_PER_BLOCK + 1)) {
+		if (config->rx_cfg[i].num_rxd %
+		    (rxd_count[nic->rxd_mode] + 1)) {
 			DBG_PRINT(ERR_DBG, "%s: RxD count of ", dev->name);
 			DBG_PRINT(ERR_DBG, "Ring%d is not a multiple of ",
 				  i);
@@ -467,11 +473,15 @@ static int init_shared_mem(struct s2io_n
 		}
 		size += config->rx_cfg[i].num_rxd;
 		mac_control->rings[i].block_count =
-		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
-		mac_control->rings[i].pkt_cnt =
-		    config->rx_cfg[i].num_rxd - mac_control->rings[i].block_count;
+			config->rx_cfg[i].num_rxd /
+			(rxd_count[nic->rxd_mode] + 1 );
+		mac_control->rings[i].pkt_cnt = config->rx_cfg[i].num_rxd -
+			mac_control->rings[i].block_count;
 	}
-	size = (size * (sizeof(RxD_t)));
+	if (nic->rxd_mode == RXD_MODE_1)
+		size = (size * (sizeof(RxD1_t)));
+	else
+		size = (size * (sizeof(RxD3_t)));
 	rx_sz = size;
 
 	for (i = 0; i < config->rx_ring_num; i++) {
@@ -486,15 +496,15 @@ static int init_shared_mem(struct s2io_n
 		mac_control->rings[i].nic = nic;
 		mac_control->rings[i].ring_no = i;
 
-		blk_cnt =
-		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
+		blk_cnt = config->rx_cfg[i].num_rxd /
+				(rxd_count[nic->rxd_mode] + 1);
 		/*  Allocating all the Rx blocks */
 		for (j = 0; j < blk_cnt; j++) {
-#ifndef CONFIG_2BUFF_MODE
-			size = (MAX_RXDS_PER_BLOCK + 1) * (sizeof(RxD_t));
-#else
-			size = SIZE_OF_BLOCK;
-#endif
+			rx_block_info_t *rx_blocks;
+			int l;
+
+			rx_blocks = &mac_control->rings[i].rx_blocks[j];
+			size = SIZE_OF_BLOCK; //size is always page size
 			tmp_v_addr = pci_alloc_consistent(nic->pdev, size,
 							  &tmp_p_addr);
 			if (tmp_v_addr == NULL) {
@@ -504,11 +514,24 @@ static int init_shared_mem(struct s2io_n
 				 * memory that was alloced till the
 				 * failure happened.
 				 */
-				mac_control->rings[i].rx_blocks[j].block_virt_addr =
-				    tmp_v_addr;
+				rx_blocks->block_virt_addr = tmp_v_addr;
 				return -ENOMEM;
 			}
 			memset(tmp_v_addr, 0, size);
+			rx_blocks->block_virt_addr = tmp_v_addr;
+			rx_blocks->block_dma_addr = tmp_p_addr;
+			rx_blocks->rxds = kmalloc(sizeof(rxd_info_t)*
+						  rxd_count[nic->rxd_mode],
+						  GFP_KERNEL);
+			for (l=0; l<rxd_count[nic->rxd_mode];l++) {
+				rx_blocks->rxds[l].virt_addr =
+					rx_blocks->block_virt_addr +
+					(rxd_size[nic->rxd_mode] * l);
+				rx_blocks->rxds[l].dma_addr =
+					rx_blocks->block_dma_addr +
+					(rxd_size[nic->rxd_mode] * l);
+			}
+
 			mac_control->rings[i].rx_blocks[j].block_virt_addr =
 				tmp_v_addr;
 			mac_control->rings[i].rx_blocks[j].block_dma_addr =
@@ -528,62 +551,58 @@ static int init_shared_mem(struct s2io_n
 					      blk_cnt].block_dma_addr;
 
 			pre_rxd_blk = (RxD_block_t *) tmp_v_addr;
-			pre_rxd_blk->reserved_1 = END_OF_BLOCK;	/* last RxD
-								 * marker.
-								 */
-#ifndef	CONFIG_2BUFF_MODE
 			pre_rxd_blk->reserved_2_pNext_RxD_block =
 			    (unsigned long) tmp_v_addr_next;
-#endif
 			pre_rxd_blk->pNext_RxD_Blk_physical =
 			    (u64) tmp_p_addr_next;
 		}
 	}
-
-#ifdef CONFIG_2BUFF_MODE
-	/*
-	 * Allocation of Storages for buffer addresses in 2BUFF mode
-	 * and the buffers as well.
-	 */
-	for (i = 0; i < config->rx_ring_num; i++) {
-		blk_cnt =
-		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
-		mac_control->rings[i].ba = kmalloc((sizeof(buffAdd_t *) * blk_cnt),
+	if (nic->rxd_mode >= RXD_MODE_3A) {
+		/*
+		 * Allocation of Storages for buffer addresses in 2BUFF mode
+		 * and the buffers as well.
+		 */
+		for (i = 0; i < config->rx_ring_num; i++) {
+			blk_cnt = config->rx_cfg[i].num_rxd /
+			   (rxd_count[nic->rxd_mode]+ 1);
+			mac_control->rings[i].ba =
+				kmalloc((sizeof(buffAdd_t *) * blk_cnt),
 				     GFP_KERNEL);
-		if (!mac_control->rings[i].ba)
-			return -ENOMEM;
-		for (j = 0; j < blk_cnt; j++) {
-			int k = 0;
-			mac_control->rings[i].ba[j] = kmalloc((sizeof(buffAdd_t) *
-						 (MAX_RXDS_PER_BLOCK + 1)),
-						GFP_KERNEL);
-			if (!mac_control->rings[i].ba[j])
+			if (!mac_control->rings[i].ba)
 				return -ENOMEM;
-			while (k != MAX_RXDS_PER_BLOCK) {
-				ba = &mac_control->rings[i].ba[j][k];
-
-				ba->ba_0_org = (void *) kmalloc
-				    (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
-				if (!ba->ba_0_org)
-					return -ENOMEM;
-				tmp = (unsigned long) ba->ba_0_org;
-				tmp += ALIGN_SIZE;
-				tmp &= ~((unsigned long) ALIGN_SIZE);
-				ba->ba_0 = (void *) tmp;
-
-				ba->ba_1_org = (void *) kmalloc
-				    (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
-				if (!ba->ba_1_org)
+			for (j = 0; j < blk_cnt; j++) {
+				int k = 0;
+				mac_control->rings[i].ba[j] =
+					kmalloc((sizeof(buffAdd_t) *
+						(rxd_count[nic->rxd_mode] + 1)),
+						GFP_KERNEL);
+				if (!mac_control->rings[i].ba[j])
 					return -ENOMEM;
-				tmp = (unsigned long) ba->ba_1_org;
-				tmp += ALIGN_SIZE;
-				tmp &= ~((unsigned long) ALIGN_SIZE);
-				ba->ba_1 = (void *) tmp;
-				k++;
+				while (k != rxd_count[nic->rxd_mode]) {
+					ba = &mac_control->rings[i].ba[j][k];
+
+					ba->ba_0_org = (void *) kmalloc
+					    (BUF0_LEN + ALIGN_SIZE, GFP_KERNEL);
+					if (!ba->ba_0_org)
+						return -ENOMEM;
+					tmp = (unsigned long)ba->ba_0_org;
+					tmp += ALIGN_SIZE;
+					tmp &= ~((unsigned long) ALIGN_SIZE);
+					ba->ba_0 = (void *) tmp;
+
+					ba->ba_1_org = (void *) kmalloc
+					    (BUF1_LEN + ALIGN_SIZE, GFP_KERNEL);
+					if (!ba->ba_1_org)
+						return -ENOMEM;
+					tmp = (unsigned long) ba->ba_1_org;
+					tmp += ALIGN_SIZE;
+					tmp &= ~((unsigned long) ALIGN_SIZE);
+					ba->ba_1 = (void *) tmp;
+					k++;
+				}
 			}
 		}
 	}
-#endif
 
 	/* Allocation and initialization of Statistics block */
 	size = sizeof(StatInfo_t);
@@ -669,11 +688,7 @@ static void free_shared_mem(struct s2io_
 		kfree(mac_control->fifos[i].list_info);
 	}
 
-#ifndef CONFIG_2BUFF_MODE
-	size = (MAX_RXDS_PER_BLOCK + 1) * (sizeof(RxD_t));
-#else
 	size = SIZE_OF_BLOCK;
-#endif
 	for (i = 0; i < config->rx_ring_num; i++) {
 		blk_cnt = mac_control->rings[i].block_count;
 		for (j = 0; j < blk_cnt; j++) {
@@ -685,29 +700,31 @@ static void free_shared_mem(struct s2io_
 				break;
 			pci_free_consistent(nic->pdev, size,
 					    tmp_v_addr, tmp_p_addr);
+			kfree(mac_control->rings[i].rx_blocks[j].rxds);
 		}
 	}
 
-#ifdef CONFIG_2BUFF_MODE
-	/* Freeing buffer storage addresses in 2BUFF mode. */
-	for (i = 0; i < config->rx_ring_num; i++) {
-		blk_cnt =
-		    config->rx_cfg[i].num_rxd / (MAX_RXDS_PER_BLOCK + 1);
-		for (j = 0; j < blk_cnt; j++) {
-			int k = 0;
-			if (!mac_control->rings[i].ba[j])
-				continue;
-			while (k != MAX_RXDS_PER_BLOCK) {
-				buffAdd_t *ba = &mac_control->rings[i].ba[j][k];
-				kfree(ba->ba_0_org);
-				kfree(ba->ba_1_org);
-				k++;
+	if (nic->rxd_mode >= RXD_MODE_3A) {
+		/* Freeing buffer storage addresses in 2BUFF mode. */
+		for (i = 0; i < config->rx_ring_num; i++) {
+			blk_cnt = config->rx_cfg[i].num_rxd /
+			    (rxd_count[nic->rxd_mode] + 1);
+			for (j = 0; j < blk_cnt; j++) {
+				int k = 0;
+				if (!mac_control->rings[i].ba[j])
+					continue;
+				while (k != rxd_count[nic->rxd_mode]) {
+					buffAdd_t *ba =
+						&mac_control->rings[i].ba[j][k];
+					kfree(ba->ba_0_org);
+					kfree(ba->ba_1_org);
+					k++;
+				}
+				kfree(mac_control->rings[i].ba[j]);
 			}
-			kfree(mac_control->rings[i].ba[j]);
+			kfree(mac_control->rings[i].ba);
 		}
-		kfree(mac_control->rings[i].ba);
 	}
-#endif
 
 	if (mac_control->stats_mem) {
 		pci_free_consistent(nic->pdev,
@@ -1894,20 +1911,19 @@ static int start_nic(struct s2io_nic *ni
 		val64 = readq(&bar0->prc_ctrl_n[i]);
 		if (nic->config.bimodal)
 			val64 |= PRC_CTRL_BIMODAL_INTERRUPT;
-#ifndef CONFIG_2BUFF_MODE
-		val64 |= PRC_CTRL_RC_ENABLED;
-#else
-		val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3;
-#endif
+		if (nic->rxd_mode == RXD_MODE_1)
+			val64 |= PRC_CTRL_RC_ENABLED;
+		else
+			val64 |= PRC_CTRL_RC_ENABLED | PRC_CTRL_RING_MODE_3;
 		writeq(val64, &bar0->prc_ctrl_n[i]);
 	}
 
-#ifdef CONFIG_2BUFF_MODE
-	/* Enabling 2 buffer mode by writing into Rx_pa_cfg reg. */
-	val64 = readq(&bar0->rx_pa_cfg);
-	val64 |= RX_PA_CFG_IGNORE_L2_ERR;
-	writeq(val64, &bar0->rx_pa_cfg);
-#endif
+	if (nic->rxd_mode == RXD_MODE_3B) {
+		/* Enabling 2 buffer mode by writing into Rx_pa_cfg reg. */
+		val64 = readq(&bar0->rx_pa_cfg);
+		val64 |= RX_PA_CFG_IGNORE_L2_ERR;
+		writeq(val64, &bar0->rx_pa_cfg);
+	}
 
 	/*
 	 * Enabling MC-RLDRAM. After enabling the device, we timeout
@@ -2090,6 +2106,41 @@ static void stop_nic(struct s2io_nic *ni
 	}
 }
 
+int fill_rxd_3buf(nic_t *nic, RxD_t *rxdp, struct sk_buff *skb)
+{
+	struct net_device *dev = nic->dev;
+	struct sk_buff *frag_list;
+	u64 tmp;
+
+	/* Buffer-1 receives L3/L4 headers */
+	((RxD3_t*)rxdp)->Buffer1_ptr = pci_map_single
+			(nic->pdev, skb->data, l3l4hdr_size + 4,
+			PCI_DMA_FROMDEVICE);
+
+	/* skb_shinfo(skb)->frag_list will have L4 data payload */
+	skb_shinfo(skb)->frag_list = dev_alloc_skb(dev->mtu + ALIGN_SIZE);
+	if (skb_shinfo(skb)->frag_list == NULL) {
+		DBG_PRINT(ERR_DBG, "%s: dev_alloc_skb failed\n ", dev->name);
+		return -ENOMEM ;
+	}
+	frag_list = skb_shinfo(skb)->frag_list;
+	frag_list->next = NULL;
+	tmp = (u64) frag_list->data;
+	tmp += ALIGN_SIZE;
+	tmp &= ~ALIGN_SIZE;
+	frag_list->data = (void *) tmp;
+	frag_list->tail = (void *) tmp;
+
+	/* Buffer-2 receives L4 data payload */
+	((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev,
+				frag_list->data, dev->mtu,
+				PCI_DMA_FROMDEVICE);
+	rxdp->Control_2 |= SET_BUFFER1_SIZE_3(l3l4hdr_size + 4);
+	rxdp->Control_2 |= SET_BUFFER2_SIZE_3(dev->mtu);
+
+	return SUCCESS;
+}
+
 /**
  *  fill_rx_buffers - Allocates the Rx side skbs
  *  @nic:  device private variable
@@ -2117,18 +2168,12 @@ int fill_rx_buffers(struct s2io_nic *nic
 	struct sk_buff *skb;
 	RxD_t *rxdp;
 	int off, off1, size, block_no, block_no1;
-	int offset, offset1;
 	u32 alloc_tab = 0;
 	u32 alloc_cnt;
 	mac_info_t *mac_control;
 	struct config_param *config;
-#ifdef CONFIG_2BUFF_MODE
-	RxD_t *rxdpnext;
-	int nextblk;
 	u64 tmp;
 	buffAdd_t *ba;
-	dma_addr_t rxdpphys;
-#endif
 #ifndef CONFIG_S2IO_NAPI
 	unsigned long flags;
 #endif
@@ -2138,8 +2183,6 @@ int fill_rx_buffers(struct s2io_nic *nic
 	config = &nic->config;
 	alloc_cnt = mac_control->rings[ring_no].pkt_cnt -
 	    atomic_read(&nic->rx_bufs_left[ring_no]);
-	size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE +
-	    HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
 
 	while (alloc_tab < alloc_cnt) {
 		block_no = mac_control->rings[ring_no].rx_curr_put_info.
@@ -2148,159 +2191,145 @@ int fill_rx_buffers(struct s2io_nic *nic
 		    block_index;
 		off = mac_control->rings[ring_no].rx_curr_put_info.offset;
 		off1 = mac_control->rings[ring_no].rx_curr_get_info.offset;
-#ifndef CONFIG_2BUFF_MODE
-		offset = block_no * (MAX_RXDS_PER_BLOCK + 1) + off;
-		offset1 = block_no1 * (MAX_RXDS_PER_BLOCK + 1) + off1;
-#else
-		offset = block_no * (MAX_RXDS_PER_BLOCK) + off;
-		offset1 = block_no1 * (MAX_RXDS_PER_BLOCK) + off1;
-#endif
 
-		rxdp = mac_control->rings[ring_no].rx_blocks[block_no].
-		    block_virt_addr + off;
-		if ((offset == offset1) && (rxdp->Host_Control)) {
-			DBG_PRINT(INTR_DBG, "%s: Get and Put", dev->name);
+		rxdp = mac_control->rings[ring_no].
+				rx_blocks[block_no].rxds[off].virt_addr;
+
+		if ((block_no == block_no1) && (off == off1) &&
+					(rxdp->Host_Control)) {
+			DBG_PRINT(INTR_DBG, "%s: Get and Put",
+				  dev->name);
 			DBG_PRINT(INTR_DBG, " info equated\n");
 			goto end;
 		}
-#ifndef	CONFIG_2BUFF_MODE
-		if (rxdp->Control_1 == END_OF_BLOCK) {
+		if (off && (off == rxd_count[nic->rxd_mode])) {
 			mac_control->rings[ring_no].rx_curr_put_info.
 			    block_index++;
+			if (mac_control->rings[ring_no].rx_curr_put_info.
+			    block_index == mac_control->rings[ring_no].
+					block_count)
+				mac_control->rings[ring_no].rx_curr_put_info.
+					block_index = 0;
+			block_no = mac_control->rings[ring_no].
+					rx_curr_put_info.block_index;
+			if (off == rxd_count[nic->rxd_mode])
+				off = 0;
 			mac_control->rings[ring_no].rx_curr_put_info.
-			    block_index %= mac_control->rings[ring_no].block_count;
-			block_no = mac_control->rings[ring_no].rx_curr_put_info.
-				block_index;
-			off++;
-			off %= (MAX_RXDS_PER_BLOCK + 1);
-			mac_control->rings[ring_no].rx_curr_put_info.offset =
-			    off;
-			rxdp = (RxD_t *) ((unsigned long) rxdp->Control_2);
+				offset = off;
+			rxdp = mac_control->rings[ring_no].
+				rx_blocks[block_no].block_virt_addr;
 			DBG_PRINT(INTR_DBG, "%s: Next block at: %p\n",
 				  dev->name, rxdp);
 		}
 #ifndef CONFIG_S2IO_NAPI
 		spin_lock_irqsave(&nic->put_lock, flags);
 		mac_control->rings[ring_no].put_pos =
-		    (block_no * (MAX_RXDS_PER_BLOCK + 1)) + off;
+		    (block_no * (rxd_count[nic->rxd_mode] + 1)) + off;
 		spin_unlock_irqrestore(&nic->put_lock, flags);
 #endif
-#else
-		if (rxdp->Host_Control == END_OF_BLOCK) {
-			mac_control->rings[ring_no].rx_curr_put_info.
-			    block_index++;
-			mac_control->rings[ring_no].rx_curr_put_info.block_index
-			    %= mac_control->rings[ring_no].block_count;
-			block_no = mac_control->rings[ring_no].rx_curr_put_info
-			    .block_index;
-			off = 0;
-			DBG_PRINT(INTR_DBG, "%s: block%d at: 0x%llx\n",
-				  dev->name, block_no,
-				  (unsigned long long) rxdp->Control_1);
-			mac_control->rings[ring_no].rx_curr_put_info.offset =
-			    off;
-			rxdp = mac_control->rings[ring_no].rx_blocks[block_no].
-			    block_virt_addr;
-		}
-#ifndef CONFIG_S2IO_NAPI
-		spin_lock_irqsave(&nic->put_lock, flags);
-		mac_control->rings[ring_no].put_pos = (block_no *
-					 (MAX_RXDS_PER_BLOCK + 1)) + off;
-		spin_unlock_irqrestore(&nic->put_lock, flags);
-#endif
-#endif
-
-#ifndef	CONFIG_2BUFF_MODE
-		if (rxdp->Control_1 & RXD_OWN_XENA)
-#else
-		if (rxdp->Control_2 & BIT(0))
-#endif
-		{
+		if ((rxdp->Control_1 & RXD_OWN_XENA) &&
+			((nic->rxd_mode >= RXD_MODE_3A) &&
+				(rxdp->Control_2 & BIT(0)))) {
 			mac_control->rings[ring_no].rx_curr_put_info.
-			    offset = off;
+					offset = off;
 			goto end;
 		}
-#ifdef	CONFIG_2BUFF_MODE
-		/*
-		 * RxDs Spanning cache lines will be replenished only
-		 * if the succeeding RxD is also owned by Host. It
-		 * will always be the ((8*i)+3) and ((8*i)+6)
-		 * descriptors for the 48 byte descriptor. The offending
-		 * decsriptor is of-course the 3rd descriptor.
-		 */
-		rxdpphys = mac_control->rings[ring_no].rx_blocks[block_no].
-		    block_dma_addr + (off * sizeof(RxD_t));
-		if (((u64) (rxdpphys)) % 128 > 80) {
-			rxdpnext = mac_control->rings[ring_no].rx_blocks[block_no].
-			    block_virt_addr + (off + 1);
-			if (rxdpnext->Host_Control == END_OF_BLOCK) {
-				nextblk = (block_no + 1) %
-				    (mac_control->rings[ring_no].block_count);
-				rxdpnext = mac_control->rings[ring_no].rx_blocks
-				    [nextblk].block_virt_addr;
-			}
-			if (rxdpnext->Control_2 & BIT(0))
-				goto end;
-		}
-#endif
+		/* calculate size of skb based on ring mode */
+		size = dev->mtu + HEADER_ETHERNET_II_802_3_SIZE +
+				HEADER_802_2_SIZE + HEADER_SNAP_SIZE;
+		if (nic->rxd_mode == RXD_MODE_1)
+			size += NET_IP_ALIGN;
+		else if (nic->rxd_mode == RXD_MODE_3B)
+			size = dev->mtu + ALIGN_SIZE + BUF0_LEN + 4;
+		else
+			size = l3l4hdr_size + ALIGN_SIZE + BUF0_LEN + 4;
 
-#ifndef	CONFIG_2BUFF_MODE
-		skb = dev_alloc_skb(size + NET_IP_ALIGN);
-#else
-		skb = dev_alloc_skb(dev->mtu + ALIGN_SIZE + BUF0_LEN + 4);
-#endif
-		if (!skb) {
+		/* allocate skb */
+		skb = dev_alloc_skb(size);
+		if(!skb) {
 			DBG_PRINT(ERR_DBG, "%s: Out of ", dev->name);
 			DBG_PRINT(ERR_DBG, "memory to allocate SKBs\n");
 			if (first_rxdp) {
 				wmb();
 				first_rxdp->Control_1 |= RXD_OWN_XENA;
 			}
-			return -ENOMEM;
+			return -ENOMEM ;
+		}
+		if (nic->rxd_mode == RXD_MODE_1) {
+			/* 1 buffer mode - normal operation mode */
+			memset(rxdp, 0, sizeof(RxD1_t));
+			skb_reserve(skb, NET_IP_ALIGN);
+			((RxD1_t*)rxdp)->Buffer0_ptr = pci_map_single
+			    (nic->pdev, skb->data, size, PCI_DMA_FROMDEVICE);
+			rxdp->Control_2 &= (~MASK_BUFFER0_SIZE_1);
+			rxdp->Control_2 |= SET_BUFFER0_SIZE_1(size);
+
+		} else if (nic->rxd_mode >= RXD_MODE_3A) {
+			/*
+			 * 2 or 3 buffer mode -
+			 * Both 2 buffer mode and 3 buffer mode provides 128
+			 * byte aligned receive buffers.
+			 *
+			 * 3 buffer mode provides header separation where in
+			 * skb->data will have L3/L4 headers where as
+			 * skb_shinfo(skb)->frag_list will have the L4 data
+			 * payload
+			 */
+
+			memset(rxdp, 0, sizeof(RxD3_t));
+			ba = &mac_control->rings[ring_no].ba[block_no][off];
+			skb_reserve(skb, BUF0_LEN);
+			tmp = (u64)(unsigned long) skb->data;
+			tmp += ALIGN_SIZE;
+			tmp &= ~ALIGN_SIZE;
+			skb->data = (void *) (unsigned long)tmp;
+			skb->tail = (void *) (unsigned long)tmp;
+
+			((RxD3_t*)rxdp)->Buffer0_ptr =
+			    pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
+					   PCI_DMA_FROMDEVICE);
+			rxdp->Control_2 = SET_BUFFER0_SIZE_3(BUF0_LEN);
+			if (nic->rxd_mode == RXD_MODE_3B) {
+				/* Two buffer mode */
+
+				/*
+				 * Buffer2 will have L3/L4 header plus 
+				 * L4 payload
+				 */
+				((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single
+				(nic->pdev, skb->data, dev->mtu + 4,
+						PCI_DMA_FROMDEVICE);
+
+				/* Buffer-1 will be dummy buffer not used */
+				((RxD3_t*)rxdp)->Buffer1_ptr =
+				pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN,
+					PCI_DMA_FROMDEVICE);
+				rxdp->Control_2 |= SET_BUFFER1_SIZE_3(1);
+				rxdp->Control_2 |= SET_BUFFER2_SIZE_3
+								(dev->mtu + 4);
+			} else {
+				/* 3 buffer mode */
+				if (fill_rxd_3buf(nic, rxdp, skb) == -ENOMEM) {
+					dev_kfree_skb_irq(skb);
+					if (first_rxdp) {
+						wmb();
+						first_rxdp->Control_1 |=
+							RXD_OWN_XENA;
+					}
+					return -ENOMEM ;
+				}
+			}
+			rxdp->Control_2 |= BIT(0);
 		}
-#ifndef	CONFIG_2BUFF_MODE
-		skb_reserve(skb, NET_IP_ALIGN);
-		memset(rxdp, 0, sizeof(RxD_t));
-		rxdp->Buffer0_ptr = pci_map_single
-		    (nic->pdev, skb->data, size, PCI_DMA_FROMDEVICE);
-		rxdp->Control_2 &= (~MASK_BUFFER0_SIZE);
-		rxdp->Control_2 |= SET_BUFFER0_SIZE(size);
 		rxdp->Host_Control = (unsigned long) (skb);
 		if (alloc_tab & ((1 << rxsync_frequency) - 1))
 			rxdp->Control_1 |= RXD_OWN_XENA;
 		off++;
-		off %= (MAX_RXDS_PER_BLOCK + 1);
-		mac_control->rings[ring_no].rx_curr_put_info.offset = off;
-#else
-		ba = &mac_control->rings[ring_no].ba[block_no][off];
-		skb_reserve(skb, BUF0_LEN);
-		tmp = ((unsigned long) skb->data & ALIGN_SIZE);
-		if (tmp)
-			skb_reserve(skb, (ALIGN_SIZE + 1) - tmp);
-
-		memset(rxdp, 0, sizeof(RxD_t));
-		rxdp->Buffer2_ptr = pci_map_single
-		    (nic->pdev, skb->data, dev->mtu + BUF0_LEN + 4,
-		     PCI_DMA_FROMDEVICE);
-		rxdp->Buffer0_ptr =
-		    pci_map_single(nic->pdev, ba->ba_0, BUF0_LEN,
-				   PCI_DMA_FROMDEVICE);
-		rxdp->Buffer1_ptr =
-		    pci_map_single(nic->pdev, ba->ba_1, BUF1_LEN,
-				   PCI_DMA_FROMDEVICE);
-
-		rxdp->Control_2 = SET_BUFFER2_SIZE(dev->mtu + 4);
-		rxdp->Control_2 |= SET_BUFFER0_SIZE(BUF0_LEN);
-		rxdp->Control_2 |= SET_BUFFER1_SIZE(1);	/* dummy. */
-		rxdp->Control_2 |= BIT(0);	/* Set Buffer_Empty bit. */
-		rxdp->Host_Control = (u64) ((unsigned long) (skb));
-		if (alloc_tab & ((1 << rxsync_frequency) - 1))
-			rxdp->Control_1 |= RXD_OWN_XENA;
-		off++;
+		if (off == (rxd_count[nic->rxd_mode] + 1))
+			off = 0;
 		mac_control->rings[ring_no].rx_curr_put_info.offset = off;
-#endif
-		rxdp->Control_2 |= SET_RXD_MARKER;
 
+		rxdp->Control_2 |= SET_RXD_MARKER;
 		if (!(alloc_tab & ((1 << rxsync_frequency) - 1))) {
 			if (first_rxdp) {
 				wmb();
@@ -2325,6 +2354,67 @@ int fill_rx_buffers(struct s2io_nic *nic
 	return SUCCESS;
 }
 
+static void free_rxd_blk(struct s2io_nic *sp, int ring_no, int blk)
+{
+	struct net_device *dev = sp->dev;
+	int j;
+	struct sk_buff *skb;
+	RxD_t *rxdp;
+	mac_info_t *mac_control;
+	buffAdd_t *ba;
+
+	mac_control = &sp->mac_control;
+	for (j = 0 ; j < rxd_count[sp->rxd_mode]; j++) {
+		rxdp = mac_control->rings[ring_no].
+                                rx_blocks[blk].rxds[j].virt_addr;
+		skb = (struct sk_buff *)
+			((unsigned long) rxdp->Host_Control);
+		if (!skb) {
+			continue;
+		}
+		if (sp->rxd_mode == RXD_MODE_1) {
+			pci_unmap_single(sp->pdev, (dma_addr_t)
+				 ((RxD1_t*)rxdp)->Buffer0_ptr,
+				 dev->mtu +
+				 HEADER_ETHERNET_II_802_3_SIZE
+				 + HEADER_802_2_SIZE +
+				 HEADER_SNAP_SIZE,
+				 PCI_DMA_FROMDEVICE);
+			memset(rxdp, 0, sizeof(RxD1_t));
+		} else if(sp->rxd_mode == RXD_MODE_3B) {
+			ba = &mac_control->rings[ring_no].
+				ba[blk][j];
+			pci_unmap_single(sp->pdev, (dma_addr_t)
+				 ((RxD3_t*)rxdp)->Buffer0_ptr,
+				 BUF0_LEN,
+				 PCI_DMA_FROMDEVICE);
+			pci_unmap_single(sp->pdev, (dma_addr_t)
+				 ((RxD3_t*)rxdp)->Buffer1_ptr,
+				 BUF1_LEN,
+				 PCI_DMA_FROMDEVICE);
+			pci_unmap_single(sp->pdev, (dma_addr_t)
+				 ((RxD3_t*)rxdp)->Buffer2_ptr,
+				 dev->mtu + 4,
+				 PCI_DMA_FROMDEVICE);
+			memset(rxdp, 0, sizeof(RxD3_t));
+		} else {
+			pci_unmap_single(sp->pdev, (dma_addr_t)
+				((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN,
+				PCI_DMA_FROMDEVICE);
+			pci_unmap_single(sp->pdev, (dma_addr_t)
+				((RxD3_t*)rxdp)->Buffer1_ptr, 
+				l3l4hdr_size + 4,
+				PCI_DMA_FROMDEVICE);
+			pci_unmap_single(sp->pdev, (dma_addr_t)
+				((RxD3_t*)rxdp)->Buffer2_ptr, dev->mtu,
+				PCI_DMA_FROMDEVICE);
+			memset(rxdp, 0, sizeof(RxD3_t));
+		}
+		dev_kfree_skb(skb);
+		atomic_dec(&sp->rx_bufs_left[ring_no]);
+	}
+}
+
 /**
  *  free_rx_buffers - Frees all Rx buffers
  *  @sp: device private variable.
@@ -2337,77 +2427,17 @@ int fill_rx_buffers(struct s2io_nic *nic
 static void free_rx_buffers(struct s2io_nic *sp)
 {
 	struct net_device *dev = sp->dev;
-	int i, j, blk = 0, off, buf_cnt = 0;
-	RxD_t *rxdp;
-	struct sk_buff *skb;
+	int i, blk = 0, buf_cnt = 0;
 	mac_info_t *mac_control;
 	struct config_param *config;
-#ifdef CONFIG_2BUFF_MODE
-	buffAdd_t *ba;
-#endif
 
 	mac_control = &sp->mac_control;
 	config = &sp->config;
 
 	for (i = 0; i < config->rx_ring_num; i++) {
-		for (j = 0, blk = 0; j < config->rx_cfg[i].num_rxd; j++) {
-			off = j % (MAX_RXDS_PER_BLOCK + 1);
-			rxdp = mac_control->rings[i].rx_blocks[blk].
-				block_virt_addr + off;
-
-#ifndef CONFIG_2BUFF_MODE
-			if (rxdp->Control_1 == END_OF_BLOCK) {
-				rxdp =
-				    (RxD_t *) ((unsigned long) rxdp->
-					       Control_2);
-				j++;
-				blk++;
-			}
-#else
-			if (rxdp->Host_Control == END_OF_BLOCK) {
-				blk++;
-				continue;
-			}
-#endif
+		for (blk = 0; blk < rx_ring_sz[i]; blk++)
+			free_rxd_blk(sp,i,blk);
 
-			if (!(rxdp->Control_1 & RXD_OWN_XENA)) {
-				memset(rxdp, 0, sizeof(RxD_t));
-				continue;
-			}
-
-			skb =
-			    (struct sk_buff *) ((unsigned long) rxdp->
-						Host_Control);
-			if (skb) {
-#ifndef CONFIG_2BUFF_MODE
-				pci_unmap_single(sp->pdev, (dma_addr_t)
-						 rxdp->Buffer0_ptr,
-						 dev->mtu +
-						 HEADER_ETHERNET_II_802_3_SIZE
-						 + HEADER_802_2_SIZE +
-						 HEADER_SNAP_SIZE,
-						 PCI_DMA_FROMDEVICE);
-#else
-				ba = &mac_control->rings[i].ba[blk][off];
-				pci_unmap_single(sp->pdev, (dma_addr_t)
-						 rxdp->Buffer0_ptr,
-						 BUF0_LEN,
-						 PCI_DMA_FROMDEVICE);
-				pci_unmap_single(sp->pdev, (dma_addr_t)
-						 rxdp->Buffer1_ptr,
-						 BUF1_LEN,
-						 PCI_DMA_FROMDEVICE);
-				pci_unmap_single(sp->pdev, (dma_addr_t)
-						 rxdp->Buffer2_ptr,
-						 dev->mtu + BUF0_LEN + 4,
-						 PCI_DMA_FROMDEVICE);
-#endif
-				dev_kfree_skb(skb);
-				atomic_dec(&sp->rx_bufs_left[i]);
-				buf_cnt++;
-			}
-			memset(rxdp, 0, sizeof(RxD_t));
-		}
 		mac_control->rings[i].rx_curr_put_info.block_index = 0;
 		mac_control->rings[i].rx_curr_get_info.block_index = 0;
 		mac_control->rings[i].rx_curr_put_info.offset = 0;
@@ -2513,7 +2543,7 @@ static void rx_intr_handler(ring_info_t 
 {
 	nic_t *nic = ring_data->nic;
 	struct net_device *dev = (struct net_device *) nic->dev;
-	int get_block, get_offset, put_block, put_offset, ring_bufs;
+	int get_block, put_block, put_offset;
 	rx_curr_get_info_t get_info, put_info;
 	RxD_t *rxdp;
 	struct sk_buff *skb;
@@ -2532,21 +2562,22 @@ static void rx_intr_handler(ring_info_t 
 	get_block = get_info.block_index;
 	put_info = ring_data->rx_curr_put_info;
 	put_block = put_info.block_index;
-	ring_bufs = get_info.ring_len+1;
-	rxdp = ring_data->rx_blocks[get_block].block_virt_addr +
-		    get_info.offset;
-	get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
-		get_info.offset;
+	rxdp = ring_data->rx_blocks[get_block].rxds[get_info.offset].virt_addr;
 #ifndef CONFIG_S2IO_NAPI
 	spin_lock(&nic->put_lock);
 	put_offset = ring_data->put_pos;
 	spin_unlock(&nic->put_lock);
 #else
-	put_offset = (put_block * (MAX_RXDS_PER_BLOCK + 1)) +
+	put_offset = (put_block * (rxd_count[nic->rxd_mode] + 1)) +
 		put_info.offset;
 #endif
-	while (RXD_IS_UP2DT(rxdp) &&
-	       (((get_offset + 1) % ring_bufs) != put_offset)) {
+	while (RXD_IS_UP2DT(rxdp)) {
+		/* If your are next to put index then it's FIFO full condition */
+		if ((get_block == put_block) &&
+		    (get_info.offset + 1) == put_info.offset) {
+			DBG_PRINT(ERR_DBG, "%s: Ring Full\n",dev->name);
+			break;
+		}
 		skb = (struct sk_buff *) ((unsigned long)rxdp->Host_Control);
 		if (skb == NULL) {
 			DBG_PRINT(ERR_DBG, "%s: The skb is ",
@@ -2555,46 +2586,52 @@ static void rx_intr_handler(ring_info_t 
 			spin_unlock(&nic->rx_lock);
 			return;
 		}
-#ifndef CONFIG_2BUFF_MODE
-		pci_unmap_single(nic->pdev, (dma_addr_t)
-				 rxdp->Buffer0_ptr,
+		if (nic->rxd_mode == RXD_MODE_1) {
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+				 ((RxD1_t*)rxdp)->Buffer0_ptr,
 				 dev->mtu +
 				 HEADER_ETHERNET_II_802_3_SIZE +
 				 HEADER_802_2_SIZE +
 				 HEADER_SNAP_SIZE,
 				 PCI_DMA_FROMDEVICE);
-#else
-		pci_unmap_single(nic->pdev, (dma_addr_t)
-				 rxdp->Buffer0_ptr,
+		} else if (nic->rxd_mode == RXD_MODE_3B) {
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+				 ((RxD3_t*)rxdp)->Buffer0_ptr,
 				 BUF0_LEN, PCI_DMA_FROMDEVICE);
-		pci_unmap_single(nic->pdev, (dma_addr_t)
-				 rxdp->Buffer1_ptr,
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+				 ((RxD3_t*)rxdp)->Buffer1_ptr,
 				 BUF1_LEN, PCI_DMA_FROMDEVICE);
-		pci_unmap_single(nic->pdev, (dma_addr_t)
-				 rxdp->Buffer2_ptr,
-				 dev->mtu + BUF0_LEN + 4,
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+				 ((RxD3_t*)rxdp)->Buffer2_ptr,
+				 dev->mtu + 4,
 				 PCI_DMA_FROMDEVICE);
-#endif
+		} else {
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+					 ((RxD3_t*)rxdp)->Buffer0_ptr, BUF0_LEN,
+					 PCI_DMA_FROMDEVICE);
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+					 ((RxD3_t*)rxdp)->Buffer1_ptr,
+					 l3l4hdr_size + 4,
+					 PCI_DMA_FROMDEVICE);
+			pci_unmap_single(nic->pdev, (dma_addr_t)
+					 ((RxD3_t*)rxdp)->Buffer2_ptr,
+					 dev->mtu, PCI_DMA_FROMDEVICE);
+		}
 		rx_osm_handler(ring_data, rxdp);
 		get_info.offset++;
-		ring_data->rx_curr_get_info.offset =
-		    get_info.offset;
-		rxdp = ring_data->rx_blocks[get_block].block_virt_addr +
-		    get_info.offset;
-		if (get_info.offset &&
-		    (!(get_info.offset % MAX_RXDS_PER_BLOCK))) {
+		ring_data->rx_curr_get_info.offset = get_info.offset;
+		rxdp = ring_data->rx_blocks[get_block].
+				rxds[get_info.offset].virt_addr;
+		if (get_info.offset == rxd_count[nic->rxd_mode]) {
 			get_info.offset = 0;
-			ring_data->rx_curr_get_info.offset
-			    = get_info.offset;
+			ring_data->rx_curr_get_info.offset = get_info.offset;
 			get_block++;
-			get_block %= ring_data->block_count;
-			ring_data->rx_curr_get_info.block_index
-			    = get_block;
+			if (get_block == ring_data->block_count)
+				get_block = 0;
+			ring_data->rx_curr_get_info.block_index = get_block;
 			rxdp = ring_data->rx_blocks[get_block].block_virt_addr;
 		}
 
-		get_offset = (get_block * (MAX_RXDS_PER_BLOCK + 1)) +
-			    get_info.offset;
 #ifdef CONFIG_S2IO_NAPI
 		nic->pkts_to_process -= 1;
 		if (!nic->pkts_to_process)
@@ -3044,7 +3081,7 @@ int s2io_set_swapper(nic_t * sp)
 
 int wait_for_msix_trans(nic_t *nic, int i)
 {
-	XENA_dev_config_t __iomem *bar0 = nic->bar0;
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
 	u64 val64;
 	int ret = 0, cnt = 0;
 
@@ -3065,7 +3102,7 @@ int wait_for_msix_trans(nic_t *nic, int 
 
 void restore_xmsi_data(nic_t *nic)
 {
-	XENA_dev_config_t __iomem *bar0 = nic->bar0;
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
 	u64 val64;
 	int i;
 
@@ -3083,7 +3120,7 @@ void restore_xmsi_data(nic_t *nic)
 
 void store_xmsi_data(nic_t *nic)
 {
-	XENA_dev_config_t __iomem *bar0 = nic->bar0;
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
 	u64 val64, addr, data;
 	int i;
 
@@ -3106,7 +3143,7 @@ void store_xmsi_data(nic_t *nic)
 
 int s2io_enable_msi(nic_t *nic)
 {
-	XENA_dev_config_t __iomem *bar0 = nic->bar0;
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
 	u16 msi_ctrl, msg_val;
 	struct config_param *config = &nic->config;
 	struct net_device *dev = nic->dev;
@@ -3156,7 +3193,7 @@ int s2io_enable_msi(nic_t *nic)
 
 int s2io_enable_msi_x(nic_t *nic)
 {
-	XENA_dev_config_t __iomem *bar0 = nic->bar0;
+	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
 	u64 tx_mat, rx_mat;
 	u16 msi_control; /* Temp variable */
 	int ret, i, j, msix_indx = 1;
@@ -5537,16 +5574,7 @@ static int rx_osm_handler(ring_info_t *r
 		((unsigned long) rxdp->Host_Control);
 	int ring_no = ring_data->ring_no;
 	u16 l3_csum, l4_csum;
-#ifdef CONFIG_2BUFF_MODE
-	int buf0_len = RXD_GET_BUFFER0_SIZE(rxdp->Control_2);
-	int buf2_len = RXD_GET_BUFFER2_SIZE(rxdp->Control_2);
-	int get_block = ring_data->rx_curr_get_info.block_index;
-	int get_off = ring_data->rx_curr_get_info.offset;
-	buffAdd_t *ba = &ring_data->ba[get_block][get_off];
-	unsigned char *buff;
-#else
-	u16 len = (u16) ((RXD_GET_BUFFER0_SIZE(rxdp->Control_2)) >> 48);;
-#endif
+
 	skb->dev = dev;
 	if (rxdp->Control_1 & RXD_T_CODE) {
 		unsigned long long err = rxdp->Control_1 & RXD_T_CODE;
@@ -5563,19 +5591,36 @@ static int rx_osm_handler(ring_info_t *r
 	rxdp->Host_Control = 0;
 	sp->rx_pkt_count++;
 	sp->stats.rx_packets++;
-#ifndef CONFIG_2BUFF_MODE
-	sp->stats.rx_bytes += len;
-#else
-	sp->stats.rx_bytes += buf0_len + buf2_len;
-#endif
+	if (sp->rxd_mode == RXD_MODE_1) {
+		int len = RXD_GET_BUFFER0_SIZE_1(rxdp->Control_2);
 
-#ifndef CONFIG_2BUFF_MODE
-	skb_put(skb, len);
-#else
-	buff = skb_push(skb, buf0_len);
-	memcpy(buff, ba->ba_0, buf0_len);
-	skb_put(skb, buf2_len);
-#endif
+		sp->stats.rx_bytes += len;
+		skb_put(skb, len);
+
+	} else if (sp->rxd_mode >= RXD_MODE_3A) {
+		int get_block = ring_data->rx_curr_get_info.block_index;
+		int get_off = ring_data->rx_curr_get_info.offset;
+		int buf0_len = RXD_GET_BUFFER0_SIZE_3(rxdp->Control_2);
+		int buf2_len = RXD_GET_BUFFER2_SIZE_3(rxdp->Control_2);
+		unsigned char *buff = skb_push(skb, buf0_len);
+
+		buffAdd_t *ba = &ring_data->ba[get_block][get_off];
+		sp->stats.rx_bytes += buf0_len + buf2_len;
+		memcpy(buff, ba->ba_0, buf0_len);
+
+		if (sp->rxd_mode == RXD_MODE_3A) {
+			int buf1_len = RXD_GET_BUFFER1_SIZE_3(rxdp->Control_2);
+
+			skb_put(skb, buf1_len);
+			skb->len += buf2_len;
+			skb->data_len += buf2_len;
+			skb->truesize += buf2_len;
+			skb_put(skb_shinfo(skb)->frag_list, buf2_len);
+			sp->stats.rx_bytes += buf1_len;
+
+		} else
+			skb_put(skb, buf2_len);
+	}
 
 	if ((rxdp->Control_1 & TCP_OR_UDP_FRAME) &&
 	    (sp->rx_csum)) {
@@ -5711,6 +5756,7 @@ MODULE_VERSION(DRV_VERSION);
 
 module_param(tx_fifo_num, int, 0);
 module_param(rx_ring_num, int, 0);
+module_param(rx_ring_mode, int, 0);
 module_param_array(tx_fifo_len, uint, NULL, 0);
 module_param_array(rx_ring_sz, uint, NULL, 0);
 module_param_array(rts_frm_len, uint, NULL, 0);
@@ -5722,6 +5768,7 @@ module_param(shared_splits, int, 0);
 module_param(tmac_util_period, int, 0);
 module_param(rmac_util_period, int, 0);
 module_param(bimodal, bool, 0);
+module_param(l3l4hdr_size, int , 0);
 #ifndef CONFIG_S2IO_NAPI
 module_param(indicate_max_pkts, int, 0);
 #endif
@@ -5843,6 +5890,13 @@ Defaulting to INTA\n");
 	sp->pdev = pdev;
 	sp->high_dma_flag = dma_flag;
 	sp->device_enabled_once = FALSE;
+	if (rx_ring_mode == 1)
+		sp->rxd_mode = RXD_MODE_1;
+	if (rx_ring_mode == 2)
+		sp->rxd_mode = RXD_MODE_3B;
+	if (rx_ring_mode == 3)
+		sp->rxd_mode = RXD_MODE_3A;
+
 	sp->intr_type = dev_intr_type;
 
 	if ((pdev->device == PCI_DEVICE_ID_HERC_WIN) ||
@@ -5895,7 +5949,7 @@ Defaulting to INTA\n");
 	config->rx_ring_num = rx_ring_num;
 	for (i = 0; i < MAX_RX_RINGS; i++) {
 		config->rx_cfg[i].num_rxd = rx_ring_sz[i] *
-		    (MAX_RXDS_PER_BLOCK + 1);
+		    (rxd_count[sp->rxd_mode] + 1);
 		config->rx_cfg[i].ring_priority = i;
 	}
 
@@ -6090,9 +6144,6 @@ Defaulting to INTA\n");
 		DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
 				get_xena_rev_id(sp->pdev),
 				s2io_driver_version);
-#ifdef CONFIG_2BUFF_MODE
-		DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
-#endif
 		switch(sp->intr_type) {
 			case INTA:
 				DBG_PRINT(ERR_DBG, ", Intr type INTA");
@@ -6125,9 +6176,6 @@ Defaulting to INTA\n");
 		DBG_PRINT(ERR_DBG, "(rev %d), Version %s",
 					get_xena_rev_id(sp->pdev),
 					s2io_driver_version);
-#ifdef CONFIG_2BUFF_MODE
-		DBG_PRINT(ERR_DBG, ", Buffer mode %d",2);
-#endif
 		switch(sp->intr_type) {
 			case INTA:
 				DBG_PRINT(ERR_DBG, ", Intr type INTA");
@@ -6148,6 +6196,12 @@ Defaulting to INTA\n");
 			  sp->def_mac_addr[0].mac_addr[4],
 			  sp->def_mac_addr[0].mac_addr[5]);
 	}
+	if (sp->rxd_mode == RXD_MODE_3B)
+		DBG_PRINT(ERR_DBG, "%s: 2-Buffer mode support has been "
+			  "enabled\n",dev->name);
+	if (sp->rxd_mode == RXD_MODE_3A)
+		DBG_PRINT(ERR_DBG, "%s: 3-Buffer mode support has been "
+			  "enabled\n",dev->name);
 
 	/* Initialize device name */
 	strcpy(sp->name, dev->name);
diff --git a/drivers/net/s2io.h b/drivers/net/s2io.h
index 1cc24b5..419aad7 100644
--- a/drivers/net/s2io.h
+++ b/drivers/net/s2io.h
@@ -418,7 +418,7 @@ typedef struct list_info_hold {
 	void *list_virt_addr;
 } list_info_hold_t;
 
-/* Rx descriptor structure */
+/* Rx descriptor structure for 1 buffer mode */
 typedef struct _RxD_t {
 	u64 Host_Control;	/* reserved for host */
 	u64 Control_1;
@@ -439,49 +439,54 @@ typedef struct _RxD_t {
 #define	SET_RXD_MARKER		vBIT(THE_RXD_MARK, 0, 2)
 #define	GET_RXD_MARKER(ctrl)	((ctrl & SET_RXD_MARKER) >> 62)
 
-#ifndef CONFIG_2BUFF_MODE
-#define MASK_BUFFER0_SIZE       vBIT(0x3FFF,2,14)
-#define SET_BUFFER0_SIZE(val)   vBIT(val,2,14)
-#else
-#define MASK_BUFFER0_SIZE       vBIT(0xFF,2,14)
-#define MASK_BUFFER1_SIZE       vBIT(0xFFFF,16,16)
-#define MASK_BUFFER2_SIZE       vBIT(0xFFFF,32,16)
-#define SET_BUFFER0_SIZE(val)   vBIT(val,8,8)
-#define SET_BUFFER1_SIZE(val)   vBIT(val,16,16)
-#define SET_BUFFER2_SIZE(val)   vBIT(val,32,16)
-#endif
-
 #define MASK_VLAN_TAG           vBIT(0xFFFF,48,16)
 #define SET_VLAN_TAG(val)       vBIT(val,48,16)
 #define SET_NUM_TAG(val)       vBIT(val,16,32)
 
-#ifndef CONFIG_2BUFF_MODE
-#define RXD_GET_BUFFER0_SIZE(Control_2) (u64)((Control_2 & vBIT(0x3FFF,2,14)))
-#else
-#define RXD_GET_BUFFER0_SIZE(Control_2) (u8)((Control_2 & MASK_BUFFER0_SIZE) \
-							>> 48)
-#define RXD_GET_BUFFER1_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER1_SIZE) \
-							>> 32)
-#define RXD_GET_BUFFER2_SIZE(Control_2) (u16)((Control_2 & MASK_BUFFER2_SIZE) \
-							>> 16)
+
+} RxD_t;
+/* Rx descriptor structure for 1 buffer mode */
+typedef struct _RxD1_t {
+	struct _RxD_t h;
+
+#define MASK_BUFFER0_SIZE_1       vBIT(0x3FFF,2,14)
+#define SET_BUFFER0_SIZE_1(val)   vBIT(val,2,14)
+#define RXD_GET_BUFFER0_SIZE_1(_Control_2) \
+	(u16)((_Control_2 & MASK_BUFFER0_SIZE_1) >> 48)
+	u64 Buffer0_ptr;
+} RxD1_t;
+/* Rx descriptor structure for 3 or 2 buffer mode */
+
+typedef struct _RxD3_t {
+	struct _RxD_t h;
+
+#define MASK_BUFFER0_SIZE_3       vBIT(0xFF,2,14)
+#define MASK_BUFFER1_SIZE_3       vBIT(0xFFFF,16,16)
+#define MASK_BUFFER2_SIZE_3       vBIT(0xFFFF,32,16)
+#define SET_BUFFER0_SIZE_3(val)   vBIT(val,8,8)
+#define SET_BUFFER1_SIZE_3(val)   vBIT(val,16,16)
+#define SET_BUFFER2_SIZE_3(val)   vBIT(val,32,16)
+#define RXD_GET_BUFFER0_SIZE_3(Control_2) \
+	(u8)((Control_2 & MASK_BUFFER0_SIZE_3) >> 48)
+#define RXD_GET_BUFFER1_SIZE_3(Control_2) \
+	(u16)((Control_2 & MASK_BUFFER1_SIZE_3) >> 32)
+#define RXD_GET_BUFFER2_SIZE_3(Control_2) \
+	(u16)((Control_2 & MASK_BUFFER2_SIZE_3) >> 16)
 #define BUF0_LEN	40
 #define BUF1_LEN	1
-#endif
 
 	u64 Buffer0_ptr;
-#ifdef CONFIG_2BUFF_MODE
 	u64 Buffer1_ptr;
 	u64 Buffer2_ptr;
-#endif
-} RxD_t;
+} RxD3_t;
+
 
 /* Structure that represents the Rx descriptor block which contains
  * 128 Rx descriptors.
  */
-#ifndef CONFIG_2BUFF_MODE
 typedef struct _RxD_block {
-#define MAX_RXDS_PER_BLOCK             127
-	RxD_t rxd[MAX_RXDS_PER_BLOCK];
+#define MAX_RXDS_PER_BLOCK_1            127
+	RxD1_t rxd[MAX_RXDS_PER_BLOCK_1];
 
 	u64 reserved_0;
 #define END_OF_BLOCK    0xFEFFFFFFFFFFFFFFULL
@@ -492,18 +497,13 @@ typedef struct _RxD_block {
 					 * the upper 32 bits should
 					 * be 0 */
 } RxD_block_t;
-#else
-typedef struct _RxD_block {
-#define MAX_RXDS_PER_BLOCK             85
-	RxD_t rxd[MAX_RXDS_PER_BLOCK];
 
-#define END_OF_BLOCK    0xFEFFFFFFFFFFFFFFULL
-	u64 reserved_1;		/* 0xFEFFFFFFFFFFFFFF to mark last Rxd
-				 * in this blk */
-	u64 pNext_RxD_Blk_physical;	/* Phy ponter to next blk. */
-} RxD_block_t;
 #define SIZE_OF_BLOCK	4096
 
+#define RXD_MODE_1	0
+#define RXD_MODE_3A	1
+#define RXD_MODE_3B	2
+
 /* Structure to hold virtual addresses of Buf0 and Buf1 in
  * 2buf mode. */
 typedef struct bufAdd {
@@ -512,7 +512,6 @@ typedef struct bufAdd {
 	void *ba_0;
 	void *ba_1;
 } buffAdd_t;
-#endif
 
 /* Structure which stores all the MAC control parameters */
 
@@ -539,10 +538,17 @@ typedef struct {
 
 typedef tx_curr_get_info_t tx_curr_put_info_t;
 
+
+typedef struct rxd_info {
+	void *virt_addr;
+	dma_addr_t dma_addr;
+}rxd_info_t;
+
 /* Structure that holds the Phy and virt addresses of the Blocks */
 typedef struct rx_block_info {
-	RxD_t *block_virt_addr;
+	void *block_virt_addr;
 	dma_addr_t block_dma_addr;
+	rxd_info_t *rxds;
 } rx_block_info_t;
 
 /* pre declaration of the nic structure */
@@ -578,10 +584,8 @@ typedef struct ring_info {
 	int put_pos;
 #endif
 
-#ifdef CONFIG_2BUFF_MODE
 	/* Buffer Address store. */
 	buffAdd_t **ba;
-#endif
 	nic_t *nic;
 } ring_info_t;
 
@@ -647,8 +651,6 @@ typedef struct {
 
 /* Default Tunable parameters of the NIC. */
 #define DEFAULT_FIFO_LEN 4096
-#define SMALL_RXD_CNT	30 * (MAX_RXDS_PER_BLOCK+1)
-#define LARGE_RXD_CNT	100 * (MAX_RXDS_PER_BLOCK+1)
 #define SMALL_BLK_CNT	30
 #define LARGE_BLK_CNT	100
 
@@ -678,6 +680,7 @@ struct msix_info_st {
 
 /* Structure representing one instance of the NIC */
 struct s2io_nic {
+	int rxd_mode;
 #ifdef CONFIG_S2IO_NAPI
 	/*
 	 * Count of packets to be processed in a given iteration, it will be indicated
---
0.99.8.GIT


--- NEW FILE 2412-pcnet32-show-name-of-failing-device.txt ---
Subject: [PATCH] pcnet32: show name of failing device
From: Don Fry <brazilnut at us.ibm.com>
Date: 1130875473 -0800

Display the name eth%d or pci_name() of device which fails to allocate
memory.  When changing ring size via ethtool, it also releases the
lock before returning on error.  Added comment that the caller of
pcnet32_alloc_ring must call pcnet32_free_ring on error, to avoid leak.
Tested ia32 by forcing allocation errors.

Signed-off-by: Don Fry <brazilnut at us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/pcnet32.c |   62 ++++++++++++++++++++++++++++++++-----------------
 1 files changed, 41 insertions(+), 21 deletions(-)

applies-to: 25b9b0ad8f50733aee663973cbf2f2f4ca6eeb9f
a88c844c1748ba494d38b1053829ec046c74ebfd
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 70fe81a..31e6dd0 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -22,8 +22,8 @@
  *************************************************************************/
 
 #define DRV_NAME	"pcnet32"
-#define DRV_VERSION	"1.31a"
-#define DRV_RELDATE	"12.Sep.2005"
+#define DRV_VERSION	"1.31b"
+#define DRV_RELDATE	"06.Oct.2005"
 #define PFX		DRV_NAME ": "
 
 static const char *version =
@@ -260,6 +260,8 @@ static int homepna[MAX_UNITS];
  * v1.31   02 Sep 2005 Hubert WS Lin <wslin at tw.ibm.c0m> added set_ringparam().
  * v1.31a  12 Sep 2005 Hubert WS Lin <wslin at tw.ibm.c0m> set min ring size to 4
  *	   to allow loopback test to work unchanged.
+ * v1.31b  06 Oct 2005 Don Fry changed alloc_ring to show name of device
+ *	   if allocation fails
  */
 
 
@@ -408,7 +410,7 @@ static int pcnet32_get_regs_len(struct n
 static void pcnet32_get_regs(struct net_device *dev, struct ethtool_regs *regs,
 	void *ptr);
 static void pcnet32_purge_tx_ring(struct net_device *dev);
-static int pcnet32_alloc_ring(struct net_device *dev);
+static int pcnet32_alloc_ring(struct net_device *dev, char *name);
 static void pcnet32_free_ring(struct net_device *dev);
 
 
@@ -669,15 +671,17 @@ static int pcnet32_set_ringparam(struct 
     lp->rx_mod_mask = lp->rx_ring_size - 1;
     lp->rx_len_bits = (i << 4);
 
-    if (pcnet32_alloc_ring(dev)) {
+    if (pcnet32_alloc_ring(dev, dev->name)) {
 	pcnet32_free_ring(dev);
+	spin_unlock_irqrestore(&lp->lock, flags);
 	return -ENOMEM;
     }
 
     spin_unlock_irqrestore(&lp->lock, flags);
 
     if (pcnet32_debug & NETIF_MSG_DRV)
-	printk(KERN_INFO PFX "Ring Param Settings: RX: %d, TX: %d\n", lp->rx_ring_size, lp->tx_ring_size);
+	printk(KERN_INFO PFX "%s: Ring Param Settings: RX: %d, TX: %d\n",
+	       dev->name, lp->rx_ring_size, lp->tx_ring_size);
 
     if (netif_running(dev))
 	pcnet32_open(dev);
@@ -1340,7 +1344,8 @@ pcnet32_probe1(unsigned long ioaddr, int
     }
     lp->a = *a;
 
-    if (pcnet32_alloc_ring(dev)) {
+    /* prior to register_netdev, dev->name is not yet correct */
+    if (pcnet32_alloc_ring(dev, pci_name(lp->pci_dev))) {
 	ret = -ENOMEM;
 	goto err_free_ring;
     }
@@ -1448,48 +1453,63 @@ err_release_region:
 }
 
 
-static int pcnet32_alloc_ring(struct net_device *dev)
+/* if any allocation fails, caller must also call pcnet32_free_ring */
+static int pcnet32_alloc_ring(struct net_device *dev, char *name)
 {
     struct pcnet32_private *lp = dev->priv;
 
-    if ((lp->tx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
-	&lp->tx_ring_dma_addr)) == NULL) {
+    lp->tx_ring = pci_alloc_consistent(lp->pci_dev,
+	    sizeof(struct pcnet32_tx_head) * lp->tx_ring_size,
+	    &lp->tx_ring_dma_addr);
+    if (lp->tx_ring == NULL) {
 	if (pcnet32_debug & NETIF_MSG_DRV)
-	    printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
+	    printk("\n" KERN_ERR PFX "%s: Consistent memory allocation failed.\n",
+		    name);
 	return -ENOMEM;
     }
 
-    if ((lp->rx_ring = pci_alloc_consistent(lp->pci_dev, sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
-	&lp->rx_ring_dma_addr)) == NULL) {
+    lp->rx_ring = pci_alloc_consistent(lp->pci_dev,
+	    sizeof(struct pcnet32_rx_head) * lp->rx_ring_size,
+	    &lp->rx_ring_dma_addr);
+    if (lp->rx_ring == NULL) {
 	if (pcnet32_debug & NETIF_MSG_DRV)
-	    printk(KERN_ERR PFX "Consistent memory allocation failed.\n");
+	    printk("\n" KERN_ERR PFX "%s: Consistent memory allocation failed.\n",
+		    name);
 	return -ENOMEM;
     }
 
-    if (!(lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size, GFP_ATOMIC))) {
+    lp->tx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->tx_ring_size,
+	    GFP_ATOMIC);
+    if (!lp->tx_dma_addr) {
 	if (pcnet32_debug & NETIF_MSG_DRV)
-	    printk(KERN_ERR PFX "Memory allocation failed.\n");
+	    printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
 	return -ENOMEM;
     }
     memset(lp->tx_dma_addr, 0, sizeof(dma_addr_t) * lp->tx_ring_size);
 
-    if (!(lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size, GFP_ATOMIC))) {
+    lp->rx_dma_addr = kmalloc(sizeof(dma_addr_t) * lp->rx_ring_size,
+	    GFP_ATOMIC);
+    if (!lp->rx_dma_addr) {
 	if (pcnet32_debug & NETIF_MSG_DRV)
-	    printk(KERN_ERR PFX "Memory allocation failed.\n");
+	    printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
 	return -ENOMEM;
     }
     memset(lp->rx_dma_addr, 0, sizeof(dma_addr_t) * lp->rx_ring_size);
 
-    if (!(lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size, GFP_ATOMIC))) {
+    lp->tx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->tx_ring_size,
+	    GFP_ATOMIC);
+    if (!lp->tx_skbuff) {
 	if (pcnet32_debug & NETIF_MSG_DRV)
-	    printk(KERN_ERR PFX "Memory allocation failed.\n");
+	    printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
 	return -ENOMEM;
     }
     memset(lp->tx_skbuff, 0, sizeof(struct sk_buff *) * lp->tx_ring_size);
 
-    if (!(lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size, GFP_ATOMIC))) {
+    lp->rx_skbuff = kmalloc(sizeof(struct sk_buff *) * lp->rx_ring_size,
+	    GFP_ATOMIC);
+    if (!lp->rx_skbuff) {
 	if (pcnet32_debug & NETIF_MSG_DRV)
-	    printk(KERN_ERR PFX "Memory allocation failed.\n");
+	    printk("\n" KERN_ERR PFX "%s: Memory allocation failed.\n", name);
 	return -ENOMEM;
     }
     memset(lp->rx_skbuff, 0, sizeof(struct sk_buff *) * lp->rx_ring_size);
---
0.99.8.GIT


--- NEW FILE 2413-pcnet32-AT2700-2701-and-Bugzilla-2699-4551.txt ---
Subject: [PATCH] pcnet32: AT2700/2701 and Bugzilla 2699 & 4551
From: Don Fry <brazilnut at us.ibm.com>
Date: 1130878257 -0800

This patch is a better fix for Allied Telesyn 2700/2701 FX boards than
the change made in early January this year.  It allows the user to
select the speed/duplex via module_param, but if no selection is made,
forces the speed to 100 FD.  It fixes both Bugzilla bugs 2669 and 4551.
Tested ia32 and ppc64 by myself, and by the originator of bug 2669.

Signed-off-by: Don Fry <brazilnut at us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/pcnet32.c |   23 ++++++++++++++++-------
 1 files changed, 16 insertions(+), 7 deletions(-)

applies-to: d9897386dc4254134cc6e5ca1e6c63f76544fa43
2964bbd7048ac0c1405cc119604e29987dd165df
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 31e6dd0..549a073 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -22,8 +22,8 @@
  *************************************************************************/
 
 #define DRV_NAME	"pcnet32"
-#define DRV_VERSION	"1.31b"
-#define DRV_RELDATE	"06.Oct.2005"
+#define DRV_VERSION	"1.31c"
+#define DRV_RELDATE	"01.Nov.2005"
 #define PFX		DRV_NAME ": "
 
 static const char *version =
@@ -262,6 +262,9 @@ static int homepna[MAX_UNITS];
  *	   to allow loopback test to work unchanged.
  * v1.31b  06 Oct 2005 Don Fry changed alloc_ring to show name of device
  *	   if allocation fails
+ * v1.31c  01 Nov 2005 Don Fry Allied Telesyn 2700/2701 FX are 100Mbit only.
+ *	   Force 100Mbit FD if Auto (ASEL) is selected.
+ *	   See Bugzilla 2669 and 4551.
  */
 
 
@@ -1612,12 +1615,18 @@ pcnet32_open(struct net_device *dev)
 	val |= 0x10;
     lp->a.write_csr (ioaddr, 124, val);
 
-    /* Allied Telesyn AT 2700/2701 FX looses the link, so skip that */
+    /* Allied Telesyn AT 2700/2701 FX are 100Mbit only and do not negotiate */
     if (lp->pci_dev->subsystem_vendor == PCI_VENDOR_ID_AT &&
-        (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
-	 lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
-	printk(KERN_DEBUG "%s: Skipping PHY selection.\n", dev->name);
-    } else {
+	    (lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2700FX ||
+	     lp->pci_dev->subsystem_device == PCI_SUBDEVICE_ID_AT_2701FX)) {
+	if (lp->options & PCNET32_PORT_ASEL) {
+	    lp->options = PCNET32_PORT_FD | PCNET32_PORT_100;
+	    if (netif_msg_link(lp))
+		printk(KERN_DEBUG "%s: Setting 100Mb-Full Duplex.\n",
+			dev->name);
+	}
+    }
+    {
 	/*
 	 * 24 Jun 2004 according AMD, in order to change the PHY,
 	 * DANAS (or DISPM for 79C976) must be set; then select the speed,
---
0.99.8.GIT


--- NEW FILE 2414-pcnet32-Prevent-hang-with-79c976.txt ---
Subject: [PATCH] pcnet32: Prevent hang with 79c976
From: Don Fry <brazilnut at us.ibm.com>
Date: 1130879615 -0800

Some boards using the 79c976 pcnet32 chip will hang the system if the
ethtool --register-dump is performed with the device operational.  The
request to read bcr30 is retried by the PCI device infinitely without
returning data, hanging the system.

Tested ia32 and ppc64.

Signed-off-by:  Don Fry <brazilnut at us.ibm.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/pcnet32.c |    6 +++++-
 1 files changed, 5 insertions(+), 1 deletions(-)

applies-to: 21e64afeca8f211eb6e817d722274f3196fd4eb1
4371dc6c60705815dcfe0c2979f68a26d0b27bd4
diff --git a/drivers/net/pcnet32.c b/drivers/net/pcnet32.c
index 549a073..be31922 100644
--- a/drivers/net/pcnet32.c
+++ b/drivers/net/pcnet32.c
@@ -988,7 +988,11 @@ static void pcnet32_get_regs(struct net_
     *buff++ = a->read_csr(ioaddr, 114);
 
     /* read bus configuration registers */
-    for (i=0; i<36; i++) {
+    for (i=0; i<30; i++) {
+	*buff++ = a->read_bcr(ioaddr, i);
+    }
+    *buff++ = 0;	/* skip bcr30 so as not to hang 79C976 */
+    for (i=31; i<36; i++) {
 	*buff++ = a->read_bcr(ioaddr, i);
     }
 
---
0.99.8.GIT


--- NEW FILE 2415-phy-address-mask-support-for-generic-phy-layer.txt ---
Subject: [PATCH] phy address mask support for generic phy layer
From: Matt Porter <mporter at kernel.crashing.org>
Date: 1130973186 -0700

Adds a phy_mask field to struct mii_bus and uses it.  This field
indicates each phy address to be ignored when probing the mdio bus.

This support is needed for the fs_enet and ibm_emac drivers to be
converted to the generic phy layer among other drivers. Many systems
lock up on probing certain phy addresses or probing doesn't return
0xffff when nothing is found at the address. A new driver I'm
working on also makes use of this mask.

Signed-off-by: Matt Porter <mporter at kernel.crashing.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/phy/mdio_bus.c |    3 +++
 include/linux/phy.h        |    3 +++
 2 files changed, 6 insertions(+), 0 deletions(-)

applies-to: 75a5ca9f987603b20b05fb718324e5edd7165a3e
f896424cbc61225e8f029fe23e5aae3e32103229
diff --git a/drivers/net/phy/mdio_bus.c b/drivers/net/phy/mdio_bus.c
index ad93b0d..5eab9c4 100644
--- a/drivers/net/phy/mdio_bus.c
+++ b/drivers/net/phy/mdio_bus.c
@@ -61,6 +61,9 @@ int mdiobus_register(struct mii_bus *bus
 	for (i = 0; i < PHY_MAX_ADDR; i++) {
 		struct phy_device *phydev;
 
+		if (bus->phy_mask & (1 << i))
+			continue;
+
 		phydev = get_phy_device(bus, i);
 
 		if (IS_ERR(phydev))
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 72cb67b..92a9696 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -72,6 +72,9 @@ struct mii_bus {
 	/* list of all PHYs on bus */
 	struct phy_device *phy_map[PHY_MAX_ADDR];
 
+	/* Phy addresses to be ignored when probing */
+	u32 phy_mask;
+
 	/* Pointer to an array of interrupts, each PHY's
 	 * interrupt at the index matching its address */
 	int *irq;
---
0.99.8.GIT


--- NEW FILE 2443-DRIVER-MODEL-Fix-depca.txt ---
Subject: [PATCH] [DRIVER MODEL] Fix depca
From: Russell King <rmk at dyn-67.arm.linux.org.uk>
Date: 1131225621 +0000

Release code in driver modules is a potential cause of oopsen.
The device may be in use by a userspace process, which will keep
a reference to the device.  If the module is unloaded, the module
text will be freed.  Subsequently, when the last reference is
dropped, the release code will be called, which no longer exists.

Use generic platform device allocation/release code in modules.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
Acked-by: Greg Kroah-Hartman <gregkh at suse.de>

---

 drivers/net/depca.c |   24 +++++++-----------------
 1 files changed, 7 insertions(+), 17 deletions(-)

applies-to: ea6ee411ffb3067d0940edc5f1c357e4576c2056
5d994b7f5d1c77acaa0b9b4c1b9f0f278605c309
diff --git a/drivers/net/depca.c b/drivers/net/depca.c
index 4d26e5e..0d33a93 100644
--- a/drivers/net/depca.c
+++ b/drivers/net/depca.c
@@ -1470,15 +1470,6 @@ static int __init depca_mca_probe(struct
 ** ISA bus I/O device probe
 */
 
-static void depca_platform_release (struct device *device)
-{
-	struct platform_device *pldev;
-
-	/* free device */
-	pldev = to_platform_device (device);
-	kfree (pldev);
-}
-
 static void __init depca_platform_probe (void)
 {
 	int i;
@@ -1491,19 +1482,16 @@ static void __init depca_platform_probe 
 		 * line, use it (if valid) */
 		if (io && io != depca_io_ports[i].iobase)
 			continue;
-		
-		if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
+
+		pldev = platform_device_alloc(depca_string, i);
+		if (!pldev)
 			continue;
 
-		memset (pldev, 0, sizeof (*pldev));
-		pldev->name = depca_string;
-		pldev->id   = i;
 		pldev->dev.platform_data = (void *) depca_io_ports[i].iobase;
-		pldev->dev.release       = depca_platform_release;
 		depca_io_ports[i].device = pldev;
 
-		if (platform_device_register (pldev)) {
-			kfree (pldev);
+		if (platform_device_add(pldev)) {
+			platform_device_put(pldev);
 			depca_io_ports[i].device = NULL;
 			continue;
 		}
@@ -1515,6 +1503,7 @@ static void __init depca_platform_probe 
 		 * allocated structure */
 			
 			depca_io_ports[i].device = NULL;
+			pldev->dev.platform_data = NULL;
 			platform_device_unregister (pldev);
 		}
 	}
@@ -2112,6 +2101,7 @@ static void __exit depca_module_exit (vo
 
 	for (i = 0; depca_io_ports[i].iobase; i++) {
 		if (depca_io_ports[i].device) {
+			depca_io_ports[i].device->dev.platform_data = NULL;
 			platform_device_unregister (depca_io_ports[i].device);
 			depca_io_ports[i].device = NULL;
 		}
---
0.99.8.GIT


--- NEW FILE 2444-DRIVER-MODEL-Fix-jazzsonic.txt ---
Subject: [PATCH] [DRIVER MODEL] Fix jazzsonic
From: Russell King <rmk at dyn-67.arm.linux.org.uk>
Date: 1131225647 +0000

Release code in driver modules is a potential cause of oopsen.
The device may be in use by a userspace process, which will keep
a reference to the device.  If the module is unloaded, the module
text will be freed.  Subsequently, when the last reference is
dropped, the release code will be called, which no longer exists.

Use generic platform device allocation/release code in modules.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
Acked-by: Greg Kroah-Hartman <gregkh at suse.de>

---

 drivers/net/jazzsonic.c |   28 +++++-----------------------
 1 files changed, 5 insertions(+), 23 deletions(-)

applies-to: 6c74ec305642a6e74c522c22223ff57a96793049
95cb5d954ee656a0b048ea2298188569e0759336
diff --git a/drivers/net/jazzsonic.c b/drivers/net/jazzsonic.c
index a74a5cf..2fb3101 100644
--- a/drivers/net/jazzsonic.c
+++ b/drivers/net/jazzsonic.c
@@ -285,18 +285,8 @@ static struct device_driver jazz_sonic_d
 	.remove	= __devexit_p(jazz_sonic_device_remove),
 };
 
-static void jazz_sonic_platform_release (struct device *device)
-{
-	struct platform_device *pldev;
-
-	/* free device */
-	pldev = to_platform_device (device);
-	kfree (pldev);
-}
-
 static int __init jazz_sonic_init_module(void)
 {
-	struct platform_device *pldev;
 	int err;
 
 	if ((err = driver_register(&jazz_sonic_driver))) {
@@ -304,27 +294,19 @@ static int __init jazz_sonic_init_module
 		return err;
 	}
 
-	jazz_sonic_device = NULL;
-
-	if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
+	jazz_sonic_device = platform_device_alloc(jazz_sonic_string, 0);
+	if (!jazz_sonnic_device)
 		goto out_unregister;
-	}
 
-	memset(pldev, 0, sizeof (*pldev));
-	pldev->name		= jazz_sonic_string;
-	pldev->id		= 0;
-	pldev->dev.release	= jazz_sonic_platform_release;
-	jazz_sonic_device	= pldev;
-
-	if (platform_device_register (pldev)) {
-		kfree(pldev);
+	if (platform_device_add(jazz_sonic_device)) {
+		platform_device_put(jazz_sonic_device);
 		jazz_sonic_device = NULL;
 	}
 
 	return 0;
 
 out_unregister:
-	platform_device_unregister(pldev);
+	driver_unregister(&jazz_sonic_driver);
 
 	return -ENOMEM;
 }
---
0.99.8.GIT


--- NEW FILE 2445-DRIVER-MODEL-Fix-macsonic.txt ---
Subject: [PATCH] [DRIVER MODEL] Fix macsonic
From: Russell King <rmk at dyn-67.arm.linux.org.uk>
Date: 1131225670 +0000

Release code in driver modules is a potential cause of oopsen.
The device may be in use by a userspace process, which will keep
a reference to the device.  If the module is unloaded, the module
text will be freed.  Subsequently, when the last reference is
dropped, the release code will be called, which no longer exists.

Use generic platform device allocation/release code in modules.

Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>
Acked-by: Greg Kroah-Hartman <gregkh at suse.de>

---

 drivers/net/macsonic.c |   27 +++++----------------------
 1 files changed, 5 insertions(+), 22 deletions(-)

applies-to: 3283cd23477bad8d3a418e6f501b39145bfd54b8
09c6518ca0de24549a923891b2d335e8496d79a9
diff --git a/drivers/net/macsonic.c b/drivers/net/macsonic.c
index e9c999d..9ef4592 100644
--- a/drivers/net/macsonic.c
+++ b/drivers/net/macsonic.c
@@ -599,18 +599,8 @@ static struct device_driver mac_sonic_dr
 	.remove = __devexit_p(mac_sonic_device_remove),
 };
 
-static void mac_sonic_platform_release(struct device *device)
-{
-	struct platform_device *pldev;
-
-	/* free device */
-	pldev = to_platform_device (device);
-	kfree (pldev);
-}
-
 static int __init mac_sonic_init_module(void)
 {
-	struct platform_device *pldev;
 	int err;
 
 	if ((err = driver_register(&mac_sonic_driver))) {
@@ -618,27 +608,20 @@ static int __init mac_sonic_init_module(
 		return err;
 	}
 
-	mac_sonic_device = NULL;
-
-	if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL))) {
+	mac_sonic_device = platform_device_alloc(mac_sonic_string, 0);
+	if (!mac_sonic_device) {
 		goto out_unregister;
 	}
 
-	memset(pldev, 0, sizeof (*pldev));
-	pldev->name		= mac_sonic_string;
-	pldev->id		= 0;
-	pldev->dev.release	= mac_sonic_platform_release;
-	mac_sonic_device	= pldev;
-
-	if (platform_device_register (pldev)) {
-		kfree(pldev);
+	if (platform_device_add(mac_sonic_device)) {
+		platform_device_put(mac_sonic_device);
 		mac_sonic_device = NULL;
 	}
 
 	return 0;
 
 out_unregister:
-	platform_device_unregister(pldev);
+	driver_unregister(&mac_sonic_driver);
 
 	return -ENOMEM;
 }
---
0.99.8.GIT


--- NEW FILE 2455-drivers-net-ixgb-make-some-code-static.txt ---
Subject: [PATCH] drivers/net/ixgb/: make some code static
From: Adrian Bunk <bunk at stusta.de>
Date: 1130687610 +0100

This patch makes some needlessly global code static.

Signed-off-by: Adrian Bunk <bunk at stusta.de>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/ixgb/ixgb_ethtool.c |    2 +-
 drivers/net/ixgb/ixgb_hw.c      |   31 ++++++++++++++++++++++---------
 drivers/net/ixgb/ixgb_hw.h      |   17 -----------------
 drivers/net/ixgb/ixgb_main.c    |    2 +-
 4 files changed, 24 insertions(+), 28 deletions(-)

applies-to: 34f0675602943161c3dc1340d6c8c449283b681c
e9ab1d145365a871858f402f3655cd4939fa38d5
diff --git a/drivers/net/ixgb/ixgb_ethtool.c b/drivers/net/ixgb/ixgb_ethtool.c
index 04e4718..d38ade5 100644
--- a/drivers/net/ixgb/ixgb_ethtool.c
+++ b/drivers/net/ixgb/ixgb_ethtool.c
@@ -694,7 +694,7 @@ ixgb_get_strings(struct net_device *netd
 	}
 }
 
-struct ethtool_ops ixgb_ethtool_ops = {
+static struct ethtool_ops ixgb_ethtool_ops = {
 	.get_settings = ixgb_get_settings,
 	.set_settings = ixgb_set_settings,
 	.get_drvinfo = ixgb_get_drvinfo,
diff --git a/drivers/net/ixgb/ixgb_hw.c b/drivers/net/ixgb/ixgb_hw.c
index 69329c7..620cad4 100644
--- a/drivers/net/ixgb/ixgb_hw.c
+++ b/drivers/net/ixgb/ixgb_hw.c
@@ -47,9 +47,22 @@ static void ixgb_optics_reset(struct ixg
 
 static ixgb_phy_type ixgb_identify_phy(struct ixgb_hw *hw);
 
-uint32_t ixgb_mac_reset(struct ixgb_hw *hw);
+static void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
 
-uint32_t ixgb_mac_reset(struct ixgb_hw *hw)
+static void ixgb_clear_vfta(struct ixgb_hw *hw);
+
+static void ixgb_init_rx_addrs(struct ixgb_hw *hw);
+
+static uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
+				  uint32_t reg_address,
+				  uint32_t phy_address,
+				  uint32_t device_type);
+
+static boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
+
+static boolean_t mac_addr_valid(uint8_t *mac_addr);
+
+static uint32_t ixgb_mac_reset(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
 
@@ -335,7 +348,7 @@ ixgb_init_hw(struct ixgb_hw *hw)
  * of the receive addresss registers. Clears the multicast table. Assumes
  * the receiver is in reset when the routine is called.
  *****************************************************************************/
-void
+static void
 ixgb_init_rx_addrs(struct ixgb_hw *hw)
 {
 	uint32_t i;
@@ -604,7 +617,7 @@ ixgb_write_vfta(struct ixgb_hw *hw,
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 ixgb_clear_vfta(struct ixgb_hw *hw)
 {
 	uint32_t offset;
@@ -620,7 +633,7 @@ ixgb_clear_vfta(struct ixgb_hw *hw)
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
 
-boolean_t
+static boolean_t
 ixgb_setup_fc(struct ixgb_hw *hw)
 {
 	uint32_t ctrl_reg;
@@ -722,7 +735,7 @@ ixgb_setup_fc(struct ixgb_hw *hw)
  * This requires that first an address cycle command is sent, followed by a
  * read command.
  *****************************************************************************/
-uint16_t
+static uint16_t
 ixgb_read_phy_reg(struct ixgb_hw *hw,
 		uint32_t reg_address,
 		uint32_t phy_address,
@@ -815,7 +828,7 @@ ixgb_read_phy_reg(struct ixgb_hw *hw,
  * This requires that first an address cycle command is sent, followed by a
  * write command.
  *****************************************************************************/
-void
+static void
 ixgb_write_phy_reg(struct ixgb_hw *hw,
 			uint32_t reg_address,
 			uint32_t phy_address,
@@ -959,7 +972,7 @@ boolean_t ixgb_check_for_bad_link(struct
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 ixgb_clear_hw_cntrs(struct ixgb_hw *hw)
 {
 	volatile uint32_t temp_reg;
@@ -1114,7 +1127,7 @@ ixgb_get_bus_info(struct ixgb_hw *hw)
  * mac_addr - pointer to MAC address.
  *
  *****************************************************************************/
-boolean_t
+static boolean_t
 mac_addr_valid(uint8_t *mac_addr)
 {
 	boolean_t is_valid = TRUE;
diff --git a/drivers/net/ixgb/ixgb_hw.h b/drivers/net/ixgb/ixgb_hw.h
index 8bcf31e..382c630 100644
--- a/drivers/net/ixgb/ixgb_hw.h
+++ b/drivers/net/ixgb/ixgb_hw.h
@@ -784,23 +784,8 @@ struct ixgb_hw_stats {
 extern boolean_t ixgb_adapter_stop(struct ixgb_hw *hw);
 extern boolean_t ixgb_init_hw(struct ixgb_hw *hw);
 extern boolean_t ixgb_adapter_start(struct ixgb_hw *hw);
-extern void ixgb_init_rx_addrs(struct ixgb_hw *hw);
 extern void ixgb_check_for_link(struct ixgb_hw *hw);
 extern boolean_t ixgb_check_for_bad_link(struct ixgb_hw *hw);
-extern boolean_t ixgb_setup_fc(struct ixgb_hw *hw);
-extern void ixgb_clear_hw_cntrs(struct ixgb_hw *hw);
-extern boolean_t mac_addr_valid(uint8_t *mac_addr);
-
-extern uint16_t ixgb_read_phy_reg(struct ixgb_hw *hw,
-				uint32_t reg_addr,
-				uint32_t phy_addr,
-				uint32_t device_type);
-
-extern void ixgb_write_phy_reg(struct ixgb_hw *hw,
-				uint32_t reg_addr,
-				uint32_t phy_addr,
-				uint32_t device_type,
-				uint16_t data);
 
 extern void ixgb_rar_set(struct ixgb_hw *hw,
 				uint8_t *addr,
@@ -818,8 +803,6 @@ extern void ixgb_write_vfta(struct ixgb_
 				 uint32_t offset,
 				 uint32_t value);
 
-extern void ixgb_clear_vfta(struct ixgb_hw *hw);
-
 /* Access functions to eeprom data */
 void ixgb_get_ee_mac_addr(struct ixgb_hw *hw, uint8_t *mac_addr);
 uint32_t ixgb_get_ee_pba_number(struct ixgb_hw *hw);
diff --git a/drivers/net/ixgb/ixgb_main.c b/drivers/net/ixgb/ixgb_main.c
index 176680c..f9f77e4 100644
--- a/drivers/net/ixgb/ixgb_main.c
+++ b/drivers/net/ixgb/ixgb_main.c
@@ -45,7 +45,7 @@
  */
 
 char ixgb_driver_name[] = "ixgb";
-char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
+static char ixgb_driver_string[] = "Intel(R) PRO/10GbE Network Driver";
 
 #ifndef CONFIG_IXGB_NAPI
 #define DRIVERNAPI
---
0.99.8.GIT


--- NEW FILE 2456-drivers-net-e1000-possible-cleanups.txt ---
Subject: [PATCH] drivers/net/e1000/: possible cleanups
From: Adrian Bunk <bunk at stusta.de>
Date: 1130687614 +0100

This patch contains the following possible cleanups:
- make needlessly global code static
- #if 0 the following unused global functions:
  - e1000_hw.c: e1000_mc_addr_list_update
  - e1000_hw.c: e1000_read_reg_io
  - e1000_hw.c: e1000_enable_pciex_master

Signed-off-by: Adrian Bunk <bunk at stusta.de>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/e1000/e1000_ethtool.c |    2 -
 drivers/net/e1000/e1000_hw.c      |  101 ++++++++++++++++++++++++++-----------
 drivers/net/e1000/e1000_hw.h      |   42 ---------------
 drivers/net/e1000/e1000_main.c    |   31 ++++++-----
 4 files changed, 87 insertions(+), 89 deletions(-)

applies-to: d9a6ce83a766f3693fef16826803ed7a45121d14
3ad2cc6798be9388c9a3f1e6180e77690303eb01
diff --git a/drivers/net/e1000/e1000_ethtool.c b/drivers/net/e1000/e1000_ethtool.c
index 9c7feae..8eae8ba 100644
--- a/drivers/net/e1000/e1000_ethtool.c
+++ b/drivers/net/e1000/e1000_ethtool.c
@@ -1739,7 +1739,7 @@ e1000_get_strings(struct net_device *net
 	}
 }
 
-struct ethtool_ops e1000_ethtool_ops = {
+static struct ethtool_ops e1000_ethtool_ops = {
 	.get_settings           = e1000_get_settings,
 	.set_settings           = e1000_set_settings,
 	.get_drvinfo            = e1000_get_drvinfo,
diff --git a/drivers/net/e1000/e1000_hw.c b/drivers/net/e1000/e1000_hw.c
index 8fc876d..a267c52 100644
--- a/drivers/net/e1000/e1000_hw.c
+++ b/drivers/net/e1000/e1000_hw.c
@@ -68,6 +68,38 @@ static int32_t e1000_polarity_reversal_w
 static int32_t e1000_set_phy_mode(struct e1000_hw *hw);
 static int32_t e1000_host_if_read_cookie(struct e1000_hw *hw, uint8_t *buffer);
 static uint8_t e1000_calculate_mng_checksum(char *buffer, uint32_t length);
+static uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
+static int32_t e1000_check_downshift(struct e1000_hw *hw);
+static int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
+static void e1000_clear_hw_cntrs(struct e1000_hw *hw);
+static void e1000_clear_vfta(struct e1000_hw *hw);
+static int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
+static int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw,
+						  boolean_t link_up);
+static int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
+static int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
+static int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
+static int32_t e1000_get_cable_length(struct e1000_hw *hw,
+				      uint16_t *min_length,
+				      uint16_t *max_length);
+static int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
+static int32_t e1000_id_led_init(struct e1000_hw * hw);
+static void e1000_init_rx_addrs(struct e1000_hw *hw);
+static boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
+static int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
+static void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
+static int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset,
+				      uint16_t words, uint16_t *data);
+static int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
+static int32_t e1000_wait_autoneg(struct e1000_hw *hw);
+
+static void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset,
+			       uint32_t value);
+
+#define E1000_WRITE_REG_IO(a, reg, val) \
+	    e1000_write_reg_io((a), E1000_##reg, val)
 
 /* IGP cable length table */
 static const
@@ -2035,7 +2067,7 @@ e1000_force_mac_fc(struct e1000_hw *hw)
  * based on the flow control negotiated by the PHY. In TBI mode, the TFCE
  * and RFCE bits will be automaticaly set to the negotiated flow control mode.
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_config_fc_after_link_up(struct e1000_hw *hw)
 {
     int32_t ret_val;
@@ -2537,7 +2569,7 @@ e1000_get_speed_and_duplex(struct e1000_
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-int32_t
+static int32_t
 e1000_wait_autoneg(struct e1000_hw *hw)
 {
     int32_t ret_val;
@@ -3021,7 +3053,7 @@ e1000_phy_reset(struct e1000_hw *hw)
 *
 * hw - Struct containing variables accessed by shared code
 ******************************************************************************/
-int32_t
+static int32_t
 e1000_detect_gig_phy(struct e1000_hw *hw)
 {
     int32_t phy_init_status, ret_val;
@@ -3121,7 +3153,7 @@ e1000_phy_reset_dsp(struct e1000_hw *hw)
 * hw - Struct containing variables accessed by shared code
 * phy_info - PHY information structure
 ******************************************************************************/
-int32_t
+static int32_t
 e1000_phy_igp_get_info(struct e1000_hw *hw,
                        struct e1000_phy_info *phy_info)
 {
@@ -3195,7 +3227,7 @@ e1000_phy_igp_get_info(struct e1000_hw *
 * hw - Struct containing variables accessed by shared code
 * phy_info - PHY information structure
 ******************************************************************************/
-int32_t
+static int32_t
 e1000_phy_m88_get_info(struct e1000_hw *hw,
                        struct e1000_phy_info *phy_info)
 {
@@ -3905,7 +3937,7 @@ e1000_read_eeprom(struct e1000_hw *hw,
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_read_eeprom_eerd(struct e1000_hw *hw,
                   uint16_t offset,
                   uint16_t words,
@@ -3939,7 +3971,7 @@ e1000_read_eeprom_eerd(struct e1000_hw *
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_write_eeprom_eewr(struct e1000_hw *hw,
                    uint16_t offset,
                    uint16_t words,
@@ -3976,7 +4008,7 @@ e1000_write_eeprom_eewr(struct e1000_hw 
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd)
 {
     uint32_t attempts = 100000;
@@ -4004,7 +4036,7 @@ e1000_poll_eerd_eewr_done(struct e1000_h
 *
 * hw - Struct containing variables accessed by shared code
 ****************************************************************************/
-boolean_t
+static boolean_t
 e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw)
 {
     uint32_t eecd = 0;
@@ -4322,7 +4354,7 @@ e1000_write_eeprom_microwire(struct e100
  * data - word read from the EEPROM
  * words - number of words to read
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_commit_shadow_ram(struct e1000_hw *hw)
 {
     uint32_t attempts = 100000;
@@ -4453,7 +4485,7 @@ e1000_read_mac_addr(struct e1000_hw * hw
  * of the receive addresss registers. Clears the multicast table. Assumes
  * the receiver is in reset when the routine is called.
  *****************************************************************************/
-void
+static void
 e1000_init_rx_addrs(struct e1000_hw *hw)
 {
     uint32_t i;
@@ -4481,6 +4513,7 @@ e1000_init_rx_addrs(struct e1000_hw *hw)
     }
 }
 
+#if 0
 /******************************************************************************
  * Updates the MAC's list of multicast addresses.
  *
@@ -4564,6 +4597,7 @@ e1000_mc_addr_list_update(struct e1000_h
     }
     DEBUGOUT("MC Update Complete\n");
 }
+#endif  /*  0  */
 
 /******************************************************************************
  * Hashes an address to determine its location in the multicast table
@@ -4705,7 +4739,7 @@ e1000_write_vfta(struct e1000_hw *hw,
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 e1000_clear_vfta(struct e1000_hw *hw)
 {
     uint32_t offset;
@@ -4735,7 +4769,7 @@ e1000_clear_vfta(struct e1000_hw *hw)
     }
 }
 
-int32_t
+static int32_t
 e1000_id_led_init(struct e1000_hw * hw)
 {
     uint32_t ledctl;
@@ -4997,7 +5031,7 @@ e1000_led_off(struct e1000_hw *hw)
  *
  * hw - Struct containing variables accessed by shared code
  *****************************************************************************/
-void
+static void
 e1000_clear_hw_cntrs(struct e1000_hw *hw)
 {
     volatile uint32_t temp;
@@ -5283,6 +5317,8 @@ e1000_get_bus_info(struct e1000_hw *hw)
         break;
     }
 }
+
+#if 0
 /******************************************************************************
  * Reads a value from one of the devices registers using port I/O (as opposed
  * memory mapped I/O). Only 82544 and newer devices support port I/O.
@@ -5300,6 +5336,7 @@ e1000_read_reg_io(struct e1000_hw *hw,
     e1000_io_write(hw, io_addr, offset);
     return e1000_io_read(hw, io_data);
 }
+#endif  /*  0  */
 
 /******************************************************************************
  * Writes a value to one of the devices registers using port I/O (as opposed to
@@ -5309,7 +5346,7 @@ e1000_read_reg_io(struct e1000_hw *hw,
  * offset - offset to write to
  * value - value to write
  *****************************************************************************/
-void
+static void
 e1000_write_reg_io(struct e1000_hw *hw,
                    uint32_t offset,
                    uint32_t value)
@@ -5337,7 +5374,7 @@ e1000_write_reg_io(struct e1000_hw *hw,
  * register to the minimum and maximum range.
  * For IGP phy's, the function calculates the range by the AGC registers.
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_get_cable_length(struct e1000_hw *hw,
                        uint16_t *min_length,
                        uint16_t *max_length)
@@ -5489,7 +5526,7 @@ e1000_get_cable_length(struct e1000_hw *
  * return 0.  If the link speed is 1000 Mbps the polarity status is in the
  * IGP01E1000_PHY_PCS_INIT_REG.
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_check_polarity(struct e1000_hw *hw,
                      uint16_t *polarity)
 {
@@ -5551,7 +5588,7 @@ e1000_check_polarity(struct e1000_hw *hw
  * Link Health register.  In IGP this bit is latched high, so the driver must
  * read it immediately after link is established.
  *****************************************************************************/
-int32_t
+static int32_t
 e1000_check_downshift(struct e1000_hw *hw)
 {
     int32_t ret_val;
@@ -5592,7 +5629,7 @@ e1000_check_downshift(struct e1000_hw *h
  *
  ****************************************************************************/
 
-int32_t
+static int32_t
 e1000_config_dsp_after_link_change(struct e1000_hw *hw,
                                    boolean_t link_up)
 {
@@ -5823,7 +5860,7 @@ e1000_set_phy_mode(struct e1000_hw *hw)
  *
  ****************************************************************************/
 
-int32_t
+static int32_t
 e1000_set_d3_lplu_state(struct e1000_hw *hw,
                         boolean_t active)
 {
@@ -5936,7 +5973,7 @@ e1000_set_d3_lplu_state(struct e1000_hw 
  *
  ****************************************************************************/
 
-int32_t
+static int32_t
 e1000_set_d0_lplu_state(struct e1000_hw *hw,
                         boolean_t active)
 {
@@ -6103,7 +6140,7 @@ e1000_host_if_read_cookie(struct e1000_h
  *            timeout
  *          - E1000_SUCCESS for success.
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_mng_enable_host_if(struct e1000_hw * hw)
 {
     uint32_t hicr;
@@ -6137,7 +6174,7 @@ e1000_mng_enable_host_if(struct e1000_hw
  *
  * returns  - E1000_SUCCESS for success.
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_mng_host_if_write(struct e1000_hw * hw, uint8_t *buffer,
                         uint16_t length, uint16_t offset, uint8_t *sum)
 {
@@ -6205,7 +6242,7 @@ e1000_mng_host_if_write(struct e1000_hw 
  *
  * returns  - E1000_SUCCESS for success.
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_mng_write_cmd_header(struct e1000_hw * hw,
                            struct e1000_host_mng_command_header * hdr)
 {
@@ -6243,7 +6280,7 @@ e1000_mng_write_cmd_header(struct e1000_
  *
  * returns  - E1000_SUCCESS for success.
  ****************************************************************************/
-int32_t
+static int32_t
 e1000_mng_write_commit(
     struct e1000_hw * hw)
 {
@@ -6496,7 +6533,7 @@ e1000_polarity_reversal_workaround(struc
  * returns: - none.
  *
  ***************************************************************************/
-void
+static void
 e1000_set_pci_express_master_disable(struct e1000_hw *hw)
 {
     uint32_t ctrl;
@@ -6511,6 +6548,7 @@ e1000_set_pci_express_master_disable(str
     E1000_WRITE_REG(hw, CTRL, ctrl);
 }
 
+#if 0
 /***************************************************************************
  *
  * Enables PCI-Express master access.
@@ -6534,6 +6572,7 @@ e1000_enable_pciex_master(struct e1000_h
     ctrl &= ~E1000_CTRL_GIO_MASTER_DISABLE;
     E1000_WRITE_REG(hw, CTRL, ctrl);
 }
+#endif  /*  0  */
 
 /*******************************************************************************
  *
@@ -6584,7 +6623,7 @@ e1000_disable_pciex_master(struct e1000_
  *            E1000_SUCCESS at any other case.
  *
  ******************************************************************************/
-int32_t
+static int32_t
 e1000_get_auto_rd_done(struct e1000_hw *hw)
 {
     int32_t timeout = AUTO_READ_DONE_TIMEOUT;
@@ -6623,7 +6662,7 @@ e1000_get_auto_rd_done(struct e1000_hw *
  *            E1000_SUCCESS at any other case.
  *
  ***************************************************************************/
-int32_t
+static int32_t
 e1000_get_phy_cfg_done(struct e1000_hw *hw)
 {
     int32_t timeout = PHY_CFG_TIMEOUT;
@@ -6666,7 +6705,7 @@ e1000_get_phy_cfg_done(struct e1000_hw *
  *            E1000_SUCCESS at any other case.
  *
  ***************************************************************************/
-int32_t
+static int32_t
 e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw)
 {
     int32_t timeout;
@@ -6711,7 +6750,7 @@ e1000_get_hw_eeprom_semaphore(struct e10
  * returns: - None.
  *
  ***************************************************************************/
-void
+static void
 e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw)
 {
     uint32_t swsm;
@@ -6747,7 +6786,7 @@ e1000_check_phy_reset_block(struct e1000
 	    E1000_BLK_PHY_RESET : E1000_SUCCESS;
 }
 
-uint8_t
+static uint8_t
 e1000_arc_subsystem_valid(struct e1000_hw *hw)
 {
     uint32_t fwsm;
diff --git a/drivers/net/e1000/e1000_hw.h b/drivers/net/e1000/e1000_hw.h
index 4f2c196..76ce128 100644
--- a/drivers/net/e1000/e1000_hw.h
+++ b/drivers/net/e1000/e1000_hw.h
@@ -284,7 +284,6 @@ typedef enum {
 /* Initialization */
 int32_t e1000_reset_hw(struct e1000_hw *hw);
 int32_t e1000_init_hw(struct e1000_hw *hw);
-int32_t e1000_id_led_init(struct e1000_hw * hw);
 int32_t e1000_set_mac_type(struct e1000_hw *hw);
 void e1000_set_media_type(struct e1000_hw *hw);
 
@@ -292,10 +291,8 @@ void e1000_set_media_type(struct e1000_h
 int32_t e1000_setup_link(struct e1000_hw *hw);
 int32_t e1000_phy_setup_autoneg(struct e1000_hw *hw);
 void e1000_config_collision_dist(struct e1000_hw *hw);
-int32_t e1000_config_fc_after_link_up(struct e1000_hw *hw);
 int32_t e1000_check_for_link(struct e1000_hw *hw);
 int32_t e1000_get_speed_and_duplex(struct e1000_hw *hw, uint16_t * speed, uint16_t * duplex);
-int32_t e1000_wait_autoneg(struct e1000_hw *hw);
 int32_t e1000_force_mac_fc(struct e1000_hw *hw);
 
 /* PHY */
@@ -303,21 +300,11 @@ int32_t e1000_read_phy_reg(struct e1000_
 int32_t e1000_write_phy_reg(struct e1000_hw *hw, uint32_t reg_addr, uint16_t data);
 int32_t e1000_phy_hw_reset(struct e1000_hw *hw);
 int32_t e1000_phy_reset(struct e1000_hw *hw);
-int32_t e1000_detect_gig_phy(struct e1000_hw *hw);
 int32_t e1000_phy_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-int32_t e1000_phy_m88_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-int32_t e1000_phy_igp_get_info(struct e1000_hw *hw, struct e1000_phy_info *phy_info);
-int32_t e1000_get_cable_length(struct e1000_hw *hw, uint16_t *min_length, uint16_t *max_length);
-int32_t e1000_check_polarity(struct e1000_hw *hw, uint16_t *polarity);
-int32_t e1000_check_downshift(struct e1000_hw *hw);
 int32_t e1000_validate_mdi_setting(struct e1000_hw *hw);
 
 /* EEPROM Functions */
 int32_t e1000_init_eeprom_params(struct e1000_hw *hw);
-boolean_t e1000_is_onboard_nvm_eeprom(struct e1000_hw *hw);
-int32_t e1000_read_eeprom_eerd(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-int32_t e1000_write_eeprom_eewr(struct e1000_hw *hw, uint16_t offset, uint16_t words, uint16_t *data);
-int32_t e1000_poll_eerd_eewr_done(struct e1000_hw *hw, int eerd);
 
 /* MNG HOST IF functions */
 uint32_t e1000_enable_mng_pass_thru(struct e1000_hw *hw);
@@ -377,13 +364,6 @@ int32_t e1000_mng_write_dhcp_info(struct
 							uint16_t length);
 boolean_t e1000_check_mng_mode(struct e1000_hw *hw);
 boolean_t e1000_enable_tx_pkt_filtering(struct e1000_hw *hw);
-int32_t e1000_mng_enable_host_if(struct e1000_hw *hw);
-int32_t e1000_mng_host_if_write(struct e1000_hw *hw, uint8_t *buffer,
-                            uint16_t length, uint16_t offset, uint8_t *sum);
-int32_t e1000_mng_write_cmd_header(struct e1000_hw* hw, 
-                                   struct e1000_host_mng_command_header* hdr);
-
-int32_t e1000_mng_write_commit(struct e1000_hw *hw);
 
 int32_t e1000_read_eeprom(struct e1000_hw *hw, uint16_t reg, uint16_t words, uint16_t *data);
 int32_t e1000_validate_eeprom_checksum(struct e1000_hw *hw);
@@ -395,13 +375,10 @@ int32_t e1000_swfw_sync_acquire(struct e
 void e1000_swfw_sync_release(struct e1000_hw *hw, uint16_t mask);
 
 /* Filters (multicast, vlan, receive) */
-void e1000_init_rx_addrs(struct e1000_hw *hw);
-void e1000_mc_addr_list_update(struct e1000_hw *hw, uint8_t * mc_addr_list, uint32_t mc_addr_count, uint32_t pad, uint32_t rar_used_count);
 uint32_t e1000_hash_mc_addr(struct e1000_hw *hw, uint8_t * mc_addr);
 void e1000_mta_set(struct e1000_hw *hw, uint32_t hash_value);
 void e1000_rar_set(struct e1000_hw *hw, uint8_t * mc_addr, uint32_t rar_index);
 void e1000_write_vfta(struct e1000_hw *hw, uint32_t offset, uint32_t value);
-void e1000_clear_vfta(struct e1000_hw *hw);
 
 /* LED functions */
 int32_t e1000_setup_led(struct e1000_hw *hw);
@@ -412,7 +389,6 @@ int32_t e1000_led_off(struct e1000_hw *h
 /* Adaptive IFS Functions */
 
 /* Everything else */
-void e1000_clear_hw_cntrs(struct e1000_hw *hw);
 void e1000_reset_adaptive(struct e1000_hw *hw);
 void e1000_update_adaptive(struct e1000_hw *hw);
 void e1000_tbi_adjust_stats(struct e1000_hw *hw, struct e1000_hw_stats *stats, uint32_t frame_len, uint8_t * mac_addr);
@@ -423,29 +399,11 @@ void e1000_read_pci_cfg(struct e1000_hw 
 void e1000_write_pci_cfg(struct e1000_hw *hw, uint32_t reg, uint16_t * value);
 /* Port I/O is only supported on 82544 and newer */
 uint32_t e1000_io_read(struct e1000_hw *hw, unsigned long port);
-uint32_t e1000_read_reg_io(struct e1000_hw *hw, uint32_t offset);
 void e1000_io_write(struct e1000_hw *hw, unsigned long port, uint32_t value);
-void e1000_write_reg_io(struct e1000_hw *hw, uint32_t offset, uint32_t value);
-int32_t e1000_config_dsp_after_link_change(struct e1000_hw *hw, boolean_t link_up);
-int32_t e1000_set_d3_lplu_state(struct e1000_hw *hw, boolean_t active);
-int32_t e1000_set_d0_lplu_state(struct e1000_hw *hw, boolean_t active);
-void e1000_set_pci_express_master_disable(struct e1000_hw *hw);
-void e1000_enable_pciex_master(struct e1000_hw *hw);
 int32_t e1000_disable_pciex_master(struct e1000_hw *hw);
-int32_t e1000_get_auto_rd_done(struct e1000_hw *hw);
-int32_t e1000_get_phy_cfg_done(struct e1000_hw *hw);
 int32_t e1000_get_software_semaphore(struct e1000_hw *hw);
 void e1000_release_software_semaphore(struct e1000_hw *hw);
 int32_t e1000_check_phy_reset_block(struct e1000_hw *hw);
-int32_t e1000_get_hw_eeprom_semaphore(struct e1000_hw *hw);
-void e1000_put_hw_eeprom_semaphore(struct e1000_hw *hw);
-int32_t e1000_commit_shadow_ram(struct e1000_hw *hw);
-uint8_t e1000_arc_subsystem_valid(struct e1000_hw *hw);
-
-#define E1000_READ_REG_IO(a, reg) \
-    e1000_read_reg_io((a), E1000_##reg)
-#define E1000_WRITE_REG_IO(a, reg, val) \
-    e1000_write_reg_io((a), E1000_##reg, val)
 
 /* PCI Device IDs */
 #define E1000_DEV_ID_82542               0x1000
diff --git a/drivers/net/e1000/e1000_main.c b/drivers/net/e1000/e1000_main.c
index efbbda7..8b207f0 100644
--- a/drivers/net/e1000/e1000_main.c
+++ b/drivers/net/e1000/e1000_main.c
@@ -37,7 +37,7 @@
  */
 
 char e1000_driver_name[] = "e1000";
-char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
+static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver";
 #ifndef CONFIG_E1000_NAPI
 #define DRIVERNAPI
 #else
@@ -45,7 +45,7 @@ char e1000_driver_string[] = "Intel(R) P
 #endif
 #define DRV_VERSION "6.1.16-k2"DRIVERNAPI
 char e1000_driver_version[] = DRV_VERSION;
-char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
+static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation.";
 
 /* e1000_pci_tbl - PCI Device ID Table
  *
@@ -112,14 +112,14 @@ int e1000_setup_all_tx_resources(struct 
 int e1000_setup_all_rx_resources(struct e1000_adapter *adapter);
 void e1000_free_all_tx_resources(struct e1000_adapter *adapter);
 void e1000_free_all_rx_resources(struct e1000_adapter *adapter);
-int e1000_setup_tx_resources(struct e1000_adapter *adapter,
-                             struct e1000_tx_ring *txdr);
-int e1000_setup_rx_resources(struct e1000_adapter *adapter,
-                             struct e1000_rx_ring *rxdr);
-void e1000_free_tx_resources(struct e1000_adapter *adapter,
-                             struct e1000_tx_ring *tx_ring);
-void e1000_free_rx_resources(struct e1000_adapter *adapter,
-                             struct e1000_rx_ring *rx_ring);
+static int e1000_setup_tx_resources(struct e1000_adapter *adapter,
+				    struct e1000_tx_ring *txdr);
+static int e1000_setup_rx_resources(struct e1000_adapter *adapter,
+				    struct e1000_rx_ring *rxdr);
+static void e1000_free_tx_resources(struct e1000_adapter *adapter,
+				    struct e1000_tx_ring *tx_ring);
+static void e1000_free_rx_resources(struct e1000_adapter *adapter,
+				    struct e1000_rx_ring *rx_ring);
 void e1000_update_stats(struct e1000_adapter *adapter);
 
 /* Local Function Prototypes */
@@ -296,7 +296,8 @@ e1000_irq_enable(struct e1000_adapter *a
 		E1000_WRITE_FLUSH(&adapter->hw);
 	}
 }
-void
+
+static void
 e1000_update_mng_vlan(struct e1000_adapter *adapter)
 {
 	struct net_device *netdev = adapter->netdev;
@@ -1141,7 +1142,7 @@ e1000_check_64k_bound(struct e1000_adapt
  * Return 0 on success, negative on failure
  **/
 
-int
+static int
 e1000_setup_tx_resources(struct e1000_adapter *adapter,
                          struct e1000_tx_ring *txdr)
 {
@@ -1359,7 +1360,7 @@ e1000_configure_tx(struct e1000_adapter 
  * Returns 0 on success, negative on failure
  **/
 
-int
+static int
 e1000_setup_rx_resources(struct e1000_adapter *adapter,
                          struct e1000_rx_ring *rxdr)
 {
@@ -1747,7 +1748,7 @@ e1000_configure_rx(struct e1000_adapter 
  * Free all transmit software resources
  **/
 
-void
+static void
 e1000_free_tx_resources(struct e1000_adapter *adapter,
                         struct e1000_tx_ring *tx_ring)
 {
@@ -1858,7 +1859,7 @@ e1000_clean_all_tx_rings(struct e1000_ad
  * Free all receive software resources
  **/
 
-void
+static void
 e1000_free_rx_resources(struct e1000_adapter *adapter,
                         struct e1000_rx_ring *rx_ring)
 {
---
0.99.8.GIT


--- NEW FILE 2457-drivers-net-hamradio-dmascc.c-remove-dmascc_setup.txt ---
Subject: [PATCH] drivers/net/hamradio/dmascc.c: remove dmascc_setup()
From: Adrian Bunk <bunk at stusta.de>
Date: 1130718825 +0100

It seems dmascc_setup() is a leftover time before dmascc_init() was
there.

Signed-off-by: Adrian Bunk <bunk at stusta.de>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/hamradio/dmascc.c |   10 ----------
 1 files changed, 0 insertions(+), 10 deletions(-)

applies-to: 28389b018b626949eb5a6c4b1b0157c94a5f9ed4
e6b365f61e0bd6e8e5fd320bda78e92eafab79aa
diff --git a/drivers/net/hamradio/dmascc.c b/drivers/net/hamradio/dmascc.c
index 3be3f91..c8dc402 100644
--- a/drivers/net/hamradio/dmascc.c
+++ b/drivers/net/hamradio/dmascc.c
@@ -311,16 +311,6 @@ static void __exit dmascc_exit(void)
 	}
 }
 
-#ifndef MODULE
-void __init dmascc_setup(char *str, int *ints)
-{
-	int i;
-
-	for (i = 0; i < MAX_NUM_DEVS && i < ints[0]; i++)
-		io[i] = ints[i + 1];
-}
-#endif
-
 static int __init dmascc_init(void)
 {
 	int h, i, j, n;
---
0.99.8.GIT


--- NEW FILE 2458-prism54-Remove-redundant-assignment.txt ---
Subject: [PATCH] prism54: Remove redundant assignment
From: Daniel Drake <dsd at gentoo.org>
Date: 1131057902 +0000

The last patch I sent in ("prism54: Free skb after disabling
interrupts") included a redundant NULL assignment. Thanks to Herbert
Xu for pointing it out.

Signed-off-by: Daniel Drake <dsd at gentoo.org>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/wireless/prism54/islpci_eth.c |    1 -
 1 files changed, 0 insertions(+), 1 deletions(-)

applies-to: b294cd63ae690eed8660029f0bc52c5179a23af8
17ecc1e63b675fb43d60e84f242c848f81c5a079
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 3b49efa..fc1eb35 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -244,7 +244,6 @@ islpci_eth_transmit(struct sk_buff *skb,
 	priv->statistics.tx_dropped++;
 	spin_unlock_irqrestore(&priv->slock, flags);
 	dev_kfree_skb(skb);
-	skb = NULL;
 	return err;
 }
 
---
0.99.8.GIT


--- NEW FILE 2459-bnx2-add-5708-support.txt ---
Subject: [PATCH] bnx2: add 5708 support
From: Michael Chan <mchan at broadcom.com>
Date: 1131122749 -0800

Add 5708 copper and serdes basic support, including 2.5 Gbps support
on 5708 serdes. SPEED_2500 is also added to ethtool.h

Signed-off-by: Michael Chan <mchan at broadcom.com>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/bnx2.c      |  217 ++++++++++++++++++++++++++++++++++++++++++-----
 drivers/net/bnx2.h      |   63 +++++++++++++-
 include/linux/ethtool.h |    3 -
 include/linux/pci_ids.h |    2 
 4 files changed, 256 insertions(+), 29 deletions(-)

applies-to: f91e456f9a2a7e130878d64f826750280bbf94a4
5b0c76ad94faf95ca50fa0de9ab07460bea19568
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 11d2523..671393a 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -41,6 +41,8 @@ typedef enum {
 	NC370I,
 	BCM5706S,
 	NC370F,
+	BCM5708,
+	BCM5708S,
 } board_t;
 
 /* indexed by board_t, above */
@@ -52,6 +54,8 @@ static struct {
 	{ "HP NC370i Multifunction Gigabit Server Adapter" },
 	{ "Broadcom NetXtreme II BCM5706 1000Base-SX" },
 	{ "HP NC370F Multifunction Gigabit Server Adapter" },
+	{ "Broadcom NetXtreme II BCM5708 1000Base-T" },
+	{ "Broadcom NetXtreme II BCM5708 1000Base-SX" },
 	};
 
 static struct pci_device_id bnx2_pci_tbl[] = {
@@ -61,10 +65,14 @@ static struct pci_device_id bnx2_pci_tbl
 	  PCI_VENDOR_ID_HP, 0x3106, 0, 0, NC370I },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706 },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708 },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
 	  PCI_VENDOR_ID_HP, 0x3102, 0, 0, NC370F },
 	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5706S,
 	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5706S },
+	{ PCI_VENDOR_ID_BROADCOM, PCI_DEVICE_ID_NX2_5708S,
+	  PCI_ANY_ID, PCI_ANY_ID, 0, 0, BCM5708S },
 	{ 0, }
 };
 
@@ -430,6 +438,18 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp)
 		return;
 	}
 
+	if ((bp->phy_flags & PHY_SERDES_FLAG) &&
+	    (CHIP_NUM(bp) == CHIP_NUM_5708)) {
+		u32 val;
+
+		bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
+		if (val & BCM5708S_1000X_STAT1_TX_PAUSE)
+			bp->flow_ctrl |= FLOW_CTRL_TX;
+		if (val & BCM5708S_1000X_STAT1_RX_PAUSE)
+			bp->flow_ctrl |= FLOW_CTRL_RX;
+		return;
+	}
+
 	bnx2_read_phy(bp, MII_ADVERTISE, &local_adv);
 	bnx2_read_phy(bp, MII_LPA, &remote_adv);
 
@@ -476,7 +496,36 @@ bnx2_resolve_flow_ctrl(struct bnx2 *bp)
 }
 
 static int
-bnx2_serdes_linkup(struct bnx2 *bp)
+bnx2_5708s_linkup(struct bnx2 *bp)
+{
+	u32 val;
+
+	bp->link_up = 1;
+	bnx2_read_phy(bp, BCM5708S_1000X_STAT1, &val);
+	switch (val & BCM5708S_1000X_STAT1_SPEED_MASK) {
+		case BCM5708S_1000X_STAT1_SPEED_10:
+			bp->line_speed = SPEED_10;
+			break;
+		case BCM5708S_1000X_STAT1_SPEED_100:
+			bp->line_speed = SPEED_100;
+			break;
+		case BCM5708S_1000X_STAT1_SPEED_1G:
+			bp->line_speed = SPEED_1000;
+			break;
+		case BCM5708S_1000X_STAT1_SPEED_2G5:
+			bp->line_speed = SPEED_2500;
+			break;
+	}
+	if (val & BCM5708S_1000X_STAT1_FD)
+		bp->duplex = DUPLEX_FULL;
+	else
+		bp->duplex = DUPLEX_HALF;
+
+	return 0;
+}
+
+static int
+bnx2_5706s_linkup(struct bnx2 *bp)
 {
 	u32 bmcr, local_adv, remote_adv, common;
 
@@ -593,13 +642,27 @@ bnx2_set_mac_link(struct bnx2 *bp)
 	val = REG_RD(bp, BNX2_EMAC_MODE);
 
 	val &= ~(BNX2_EMAC_MODE_PORT | BNX2_EMAC_MODE_HALF_DUPLEX |
-		BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK);
+		BNX2_EMAC_MODE_MAC_LOOP | BNX2_EMAC_MODE_FORCE_LINK |
+		BNX2_EMAC_MODE_25G);
 
 	if (bp->link_up) {
-		if (bp->line_speed != SPEED_1000)
-			val |= BNX2_EMAC_MODE_PORT_MII;
-		else
-			val |= BNX2_EMAC_MODE_PORT_GMII;
+		switch (bp->line_speed) {
+			case SPEED_10:
+				if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+					val |= BNX2_EMAC_MODE_PORT_MII_10;
+					break;
+				}
+				/* fall through */
+			case SPEED_100:
+				val |= BNX2_EMAC_MODE_PORT_MII;
+				break;
+			case SPEED_2500:
+				val |= BNX2_EMAC_MODE_25G;
+				/* fall through */
+			case SPEED_1000:
+				val |= BNX2_EMAC_MODE_PORT_GMII;
+				break;
+		}
 	}
 	else {
 		val |= BNX2_EMAC_MODE_PORT_GMII;
@@ -662,7 +725,10 @@ bnx2_set_link(struct bnx2 *bp)
 		bp->link_up = 1;
 
 		if (bp->phy_flags & PHY_SERDES_FLAG) {
-			bnx2_serdes_linkup(bp);
+			if (CHIP_NUM(bp) == CHIP_NUM_5706)
+				bnx2_5706s_linkup(bp);
+			else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+				bnx2_5708s_linkup(bp);
 		}
 		else {
 			bnx2_copper_linkup(bp);
@@ -755,39 +821,61 @@ bnx2_phy_get_pause_adv(struct bnx2 *bp)
 static int
 bnx2_setup_serdes_phy(struct bnx2 *bp)
 {
-	u32 adv, bmcr;
+	u32 adv, bmcr, up1;
 	u32 new_adv = 0;
 
 	if (!(bp->autoneg & AUTONEG_SPEED)) {
 		u32 new_bmcr;
+		int force_link_down = 0;
+
+		if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+			bnx2_read_phy(bp, BCM5708S_UP1, &up1);
+			if (up1 & BCM5708S_UP1_2G5) {
+				up1 &= ~BCM5708S_UP1_2G5;
+				bnx2_write_phy(bp, BCM5708S_UP1, up1);
+				force_link_down = 1;
+			}
+		}
+
+		bnx2_read_phy(bp, MII_ADVERTISE, &adv);
+		adv &= ~(ADVERTISE_1000XFULL | ADVERTISE_1000XHALF);
 
 		bnx2_read_phy(bp, MII_BMCR, &bmcr);
 		new_bmcr = bmcr & ~BMCR_ANENABLE;
 		new_bmcr |= BMCR_SPEED1000;
 		if (bp->req_duplex == DUPLEX_FULL) {
+			adv |= ADVERTISE_1000XFULL;
 			new_bmcr |= BMCR_FULLDPLX;
 		}
 		else {
+			adv |= ADVERTISE_1000XHALF;
 			new_bmcr &= ~BMCR_FULLDPLX;
 		}
-		if (new_bmcr != bmcr) {
+		if ((new_bmcr != bmcr) || (force_link_down)) {
 			/* Force a link down visible on the other side */
 			if (bp->link_up) {
-				bnx2_read_phy(bp, MII_ADVERTISE, &adv);
-				adv &= ~(ADVERTISE_1000XFULL |
-					ADVERTISE_1000XHALF);
-				bnx2_write_phy(bp, MII_ADVERTISE, adv);
+				bnx2_write_phy(bp, MII_ADVERTISE, adv &
+					       ~(ADVERTISE_1000XFULL |
+						 ADVERTISE_1000XHALF));
 				bnx2_write_phy(bp, MII_BMCR, bmcr |
 					BMCR_ANRESTART | BMCR_ANENABLE);
 
 				bp->link_up = 0;
 				netif_carrier_off(bp->dev);
+				bnx2_write_phy(bp, MII_BMCR, new_bmcr);
 			}
+			bnx2_write_phy(bp, MII_ADVERTISE, adv);
 			bnx2_write_phy(bp, MII_BMCR, new_bmcr);
 		}
 		return 0;
 	}
 
+	if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
+		bnx2_read_phy(bp, BCM5708S_UP1, &up1);
+		up1 |= BCM5708S_UP1_2G5;
+		bnx2_write_phy(bp, BCM5708S_UP1, up1);
+	}
+
 	if (bp->advertising & ADVERTISED_1000baseT_Full)
 		new_adv |= ADVERTISE_1000XFULL;
 
@@ -952,7 +1040,60 @@ bnx2_setup_phy(struct bnx2 *bp)
 }
 
 static int
-bnx2_init_serdes_phy(struct bnx2 *bp)
+bnx2_init_5708s_phy(struct bnx2 *bp)
+{
+	u32 val;
+
+	bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG3);
+	bnx2_write_phy(bp, BCM5708S_DIG_3_0, BCM5708S_DIG_3_0_USE_IEEE);
+	bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
+
+	bnx2_read_phy(bp, BCM5708S_1000X_CTL1, &val);
+	val |= BCM5708S_1000X_CTL1_FIBER_MODE | BCM5708S_1000X_CTL1_AUTODET_EN;
+	bnx2_write_phy(bp, BCM5708S_1000X_CTL1, val);
+
+	bnx2_read_phy(bp, BCM5708S_1000X_CTL2, &val);
+	val |= BCM5708S_1000X_CTL2_PLLEL_DET_EN;
+	bnx2_write_phy(bp, BCM5708S_1000X_CTL2, val);
+
+	if (bp->phy_flags & PHY_2_5G_CAPABLE_FLAG) {
+		bnx2_read_phy(bp, BCM5708S_UP1, &val);
+		val |= BCM5708S_UP1_2G5;
+		bnx2_write_phy(bp, BCM5708S_UP1, val);
+	}
+
+	if ((CHIP_ID(bp) == CHIP_ID_5708_A0) ||
+	    (CHIP_ID(bp) == CHIP_ID_5708_B0)) {
+		/* increase tx signal amplitude */
+		bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+			       BCM5708S_BLK_ADDR_TX_MISC);
+		bnx2_read_phy(bp, BCM5708S_TX_ACTL1, &val);
+		val &= ~BCM5708S_TX_ACTL1_DRIVER_VCM;
+		bnx2_write_phy(bp, BCM5708S_TX_ACTL1, val);
+		bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
+	}
+
+	val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_CONFIG) &
+	      BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
+
+	if (val) {
+		u32 is_backplane;
+
+		is_backplane = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
+					  BNX2_SHARED_HW_CFG_CONFIG);
+		if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
+			bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+				       BCM5708S_BLK_ADDR_TX_MISC);
+			bnx2_write_phy(bp, BCM5708S_TX_ACTL3, val);
+			bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
+				       BCM5708S_BLK_ADDR_DIG);
+		}
+	}
+	return 0;
+}
+
+static int
+bnx2_init_5706s_phy(struct bnx2 *bp)
 {
 	bp->phy_flags &= ~PHY_PARALLEL_DETECT_FLAG;
 
@@ -990,6 +1131,8 @@ bnx2_init_serdes_phy(struct bnx2 *bp)
 static int
 bnx2_init_copper_phy(struct bnx2 *bp)
 {
+	u32 val;
+
 	bp->phy_flags |= PHY_CRC_FIX_FLAG;
 
 	if (bp->phy_flags & PHY_CRC_FIX_FLAG) {
@@ -1004,8 +1147,6 @@ bnx2_init_copper_phy(struct bnx2 *bp)
 	}
 
 	if (bp->dev->mtu > 1500) {
-		u32 val;
-
 		/* Set extended packet length bit */
 		bnx2_write_phy(bp, 0x18, 0x7);
 		bnx2_read_phy(bp, 0x18, &val);
@@ -1015,8 +1156,6 @@ bnx2_init_copper_phy(struct bnx2 *bp)
 		bnx2_write_phy(bp, 0x10, val | 0x1);
 	}
 	else {
-		u32 val;
-
 		bnx2_write_phy(bp, 0x18, 0x7);
 		bnx2_read_phy(bp, 0x18, &val);
 		bnx2_write_phy(bp, 0x18, val & ~0x4007);
@@ -1025,6 +1164,10 @@ bnx2_init_copper_phy(struct bnx2 *bp)
 		bnx2_write_phy(bp, 0x10, val & ~0x1);
 	}
 
+	/* ethernet at wirespeed */
+	bnx2_write_phy(bp, 0x18, 0x7007);
+	bnx2_read_phy(bp, 0x18, &val);
+	bnx2_write_phy(bp, 0x18, val | (1 << 15) | (1 << 4));
 	return 0;
 }
 
@@ -1048,7 +1191,10 @@ bnx2_init_phy(struct bnx2 *bp)
 	bp->phy_id |= val & 0xffff;
 
 	if (bp->phy_flags & PHY_SERDES_FLAG) {
-		rc = bnx2_init_serdes_phy(bp);
+		if (CHIP_NUM(bp) == CHIP_NUM_5706)
+			rc = bnx2_init_5706s_phy(bp);
+		else if (CHIP_NUM(bp) == CHIP_NUM_5708)
+			rc = bnx2_init_5708s_phy(bp);
 	}
 	else {
 		rc = bnx2_init_copper_phy(bp);
@@ -3234,7 +3380,7 @@ bnx2_test_registers(struct bnx2 *bp)
 		{ 0x1408, 0, 0x01c00800, 0x00000000 },
 		{ 0x149c, 0, 0x8000ffff, 0x00000000 },
 		{ 0x14a8, 0, 0x00000000, 0x000001ff },
-		{ 0x14ac, 0, 0x4fffffff, 0x10000000 },
+		{ 0x14ac, 0, 0x0fffffff, 0x10000000 },
 		{ 0x14b0, 0, 0x00000002, 0x00000001 },
 		{ 0x14b8, 0, 0x00000000, 0x00000000 },
 		{ 0x14c0, 0, 0x00000000, 0x00000009 },
@@ -3577,7 +3723,7 @@ bnx2_test_memory(struct bnx2 *bp)
 		u32   len;
 	} mem_tbl[] = {
 		{ 0x60000,  0x4000 },
-		{ 0xa0000,  0x4000 },
+		{ 0xa0000,  0x3000 },
 		{ 0xe0000,  0x4000 },
 		{ 0x120000, 0x4000 },
 		{ 0x1a0000, 0x4000 },
@@ -4264,7 +4410,8 @@ bnx2_get_stats(struct net_device *dev)
     		(unsigned long) (stats_blk->stat_Dot3StatsExcessiveCollisions +
 		stats_blk->stat_Dot3StatsLateCollisions);
 
-	if (CHIP_NUM(bp) == CHIP_NUM_5706)
+	if ((CHIP_NUM(bp) == CHIP_NUM_5706) ||
+	    (CHIP_ID(bp) == CHIP_ID_5708_A0))
 		net_stats->tx_carrier_errors = 0;
 	else {
 		net_stats->tx_carrier_errors =
@@ -4814,6 +4961,14 @@ static u8 bnx2_5706_stats_len_arr[BNX2_N
 	4,4,4,4,4,
 };
 
+static u8 bnx2_5708_stats_len_arr[BNX2_NUM_STATS] = {
+	8,0,8,8,8,8,8,8,8,8,
+	4,4,4,4,4,4,4,4,4,4,
+	4,4,4,4,4,4,4,4,4,4,
+	4,4,4,4,4,4,4,4,4,4,
+	4,4,4,4,4,
+};
+
 #define BNX2_NUM_TESTS 6
 
 static struct {
@@ -4922,8 +5077,13 @@ bnx2_get_ethtool_stats(struct net_device
 		return;
 	}
 
-	if (CHIP_NUM(bp) == CHIP_NUM_5706)
+	if ((CHIP_ID(bp) == CHIP_ID_5706_A0) ||
+	    (CHIP_ID(bp) == CHIP_ID_5706_A1) ||
+	    (CHIP_ID(bp) == CHIP_ID_5706_A2) ||
+	    (CHIP_ID(bp) == CHIP_ID_5708_A0))
 		stats_len_arr = bnx2_5706_stats_len_arr;
+	else
+		stats_len_arr = bnx2_5708_stats_len_arr;
 
 	for (i = 0; i < BNX2_NUM_STATS; i++) {
 		if (stats_len_arr[i] == 0) {
@@ -5205,8 +5365,6 @@ bnx2_init_board(struct pci_dev *pdev, st
 
 	bp->chip_id = REG_RD(bp, BNX2_MISC_ID);
 
-	bp->phy_addr = 1;
-
 	/* Get bus information. */
 	reg = REG_RD(bp, BNX2_PCICFG_MISC_STATUS);
 	if (reg & BNX2_PCICFG_MISC_STATUS_PCIX_DET) {
@@ -5316,10 +5474,19 @@ bnx2_init_board(struct pci_dev *pdev, st
 	bp->timer_interval =  HZ;
 	bp->current_interval =  HZ;
 
+	bp->phy_addr = 1;
+
 	/* Disable WOL support if we are running on a SERDES chip. */
 	if (CHIP_BOND_ID(bp) & CHIP_BOND_ID_SERDES_BIT) {
 		bp->phy_flags |= PHY_SERDES_FLAG;
 		bp->flags |= NO_WOL_FLAG;
+		if (CHIP_NUM(bp) == CHIP_NUM_5708) {
+			bp->phy_addr = 2;
+			reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
+					 BNX2_SHARED_HW_CFG_CONFIG);
+			if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
+				bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
+		}
 	}
 
 	if (CHIP_ID(bp) == CHIP_ID_5706_A0) {
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 62857b6..c0e88f8 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -1449,8 +1449,9 @@ struct l2_fhdr {
 #define BNX2_EMAC_MODE_PORT_NONE			 (0L<<2)
 #define BNX2_EMAC_MODE_PORT_MII				 (1L<<2)
 #define BNX2_EMAC_MODE_PORT_GMII			 (2L<<2)
-#define BNX2_EMAC_MODE_PORT_UNDEF			 (3L<<2)
+#define BNX2_EMAC_MODE_PORT_MII_10			 (3L<<2)
 #define BNX2_EMAC_MODE_MAC_LOOP				 (1L<<4)
+#define BNX2_EMAC_MODE_25G				 (1L<<5)
 #define BNX2_EMAC_MODE_TAGGED_MAC_CTL			 (1L<<7)
 #define BNX2_EMAC_MODE_TX_BURST				 (1L<<8)
 #define BNX2_EMAC_MODE_MAX_DEFER_DROP_ENA		 (1L<<9)
@@ -3724,6 +3725,53 @@ struct l2_fhdr {
 #define PHY_ID(id)                                  ((id) & 0xfffffff0)
 #define PHY_REV_ID(id)                              ((id) & 0xf)
 
+/* 5708 Serdes PHY registers */
+
+#define BCM5708S_UP1				0xb
+
+#define BCM5708S_UP1_2G5			0x1
+
+#define BCM5708S_BLK_ADDR			0x1f
+
+#define BCM5708S_BLK_ADDR_DIG			0x0000
+#define BCM5708S_BLK_ADDR_DIG3			0x0002
+#define BCM5708S_BLK_ADDR_TX_MISC		0x0005
+
+/* Digital Block */
+#define BCM5708S_1000X_CTL1			0x10
+
+#define BCM5708S_1000X_CTL1_FIBER_MODE		0x0001
+#define BCM5708S_1000X_CTL1_AUTODET_EN		0x0010
+
+#define BCM5708S_1000X_CTL2			0x11
+
+#define BCM5708S_1000X_CTL2_PLLEL_DET_EN	0x0001
+
+#define BCM5708S_1000X_STAT1			0x14
+
+#define BCM5708S_1000X_STAT1_SGMII		0x0001
+#define BCM5708S_1000X_STAT1_LINK		0x0002
+#define BCM5708S_1000X_STAT1_FD			0x0004
+#define BCM5708S_1000X_STAT1_SPEED_MASK		0x0018
+#define BCM5708S_1000X_STAT1_SPEED_10		0x0000
+#define BCM5708S_1000X_STAT1_SPEED_100		0x0008
+#define BCM5708S_1000X_STAT1_SPEED_1G		0x0010
+#define BCM5708S_1000X_STAT1_SPEED_2G5		0x0018
+#define BCM5708S_1000X_STAT1_TX_PAUSE		0x0020
+#define BCM5708S_1000X_STAT1_RX_PAUSE		0x0040
+
+/* Digital3 Block */
+#define BCM5708S_DIG_3_0			0x10
+
+#define BCM5708S_DIG_3_0_USE_IEEE		0x0001
+
+/* Tx/Misc Block */
+#define BCM5708S_TX_ACTL1			0x15
+
+#define BCM5708S_TX_ACTL1_DRIVER_VCM		0x30
+
+#define BCM5708S_TX_ACTL3			0x17
+
 #define MIN_ETHERNET_PACKET_SIZE	60
 #define MAX_ETHERNET_PACKET_SIZE	1514
 #define MAX_ETHERNET_JUMBO_PACKET_SIZE	9014
@@ -3893,6 +3941,7 @@ struct bnx2 {
 #define PHY_SERDES_FLAG			1
 #define PHY_CRC_FIX_FLAG		2
 #define PHY_PARALLEL_DETECT_FLAG	4
+#define PHY_2_5G_CAPABLE_FLAG		8
 #define PHY_INT_MODE_MASK_FLAG		0x300
 #define PHY_INT_MODE_AUTO_POLLING_FLAG	0x100
 #define PHY_INT_MODE_LINK_READY_FLAG	0x200
@@ -3901,6 +3950,7 @@ struct bnx2 {
 	/* chip num:16-31, rev:12-15, metal:4-11, bond_id:0-3 */
 #define CHIP_NUM(bp)			(((bp)->chip_id) & 0xffff0000)
 #define CHIP_NUM_5706			0x57060000
+#define CHIP_NUM_5708			0x57080000
 
 #define CHIP_REV(bp)			(((bp)->chip_id) & 0x0000f000)
 #define CHIP_REV_Ax			0x00000000
@@ -3913,6 +3963,9 @@ struct bnx2 {
 #define CHIP_ID(bp)			(((bp)->chip_id) & 0xfffffff0)
 #define CHIP_ID_5706_A0			0x57060000
 #define CHIP_ID_5706_A1			0x57060010
+#define CHIP_ID_5706_A2			0x57060020
+#define CHIP_ID_5708_A0			0x57080000
+#define CHIP_ID_5708_B0			0x57081000
 
 #define CHIP_BOND_ID(bp)		(((bp)->chip_id) & 0xf)
 
@@ -4132,12 +4185,12 @@ struct fw_info {
 #define BNX2_LINK_STATUS			0x0000000c
 
 #define BNX2_DRV_PULSE_MB			0x00000010
-#define BNX2_DRV_PULSE_SEQ_MASK			 0x0000ffff
+#define BNX2_DRV_PULSE_SEQ_MASK			 0x00007fff
 
 /* Indicate to the firmware not to go into the
  * OS absent when it is not getting driver pulse.
  * This is used for debugging. */
-#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE	 0x00010000
+#define BNX2_DRV_MSG_DATA_PULSE_CODE_ALWAYS_ALIVE	 0x00080000
 
 #define BNX2_DEV_INFO_SIGNATURE			0x00000020
 #define BNX2_DEV_INFO_SIGNATURE_MAGIC		 0x44564900
@@ -4160,6 +4213,8 @@ struct fw_info {
 #define BNX2_SHARED_HW_CFG_DESIGN_LOM		 0x1
 #define BNX2_SHARED_HW_CFG_PHY_COPPER		 0
 #define BNX2_SHARED_HW_CFG_PHY_FIBER		 0x2
+#define BNX2_SHARED_HW_CFG_PHY_2_5G		 0x20
+#define BNX2_SHARED_HW_CFG_PHY_BACKPLANE	 0x40
 #define BNX2_SHARED_HW_CFG_LED_MODE_SHIFT_BITS	 8
 #define BNX2_SHARED_HW_CFG_LED_MODE_MASK	 0x300
 #define BNX2_SHARED_HW_CFG_LED_MODE_MAC		 0
@@ -4173,9 +4228,11 @@ struct fw_info {
 
 #define BNX2_PORT_HW_CFG_MAC_LOWER		0x00000054
 #define BNX2_PORT_HW_CFG_CONFIG			0x00000058
+#define BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK	 0x0000ffff
 #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK	 0x001f0000
 #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_AN	 0x00000000
 #define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G	 0x00030000
+#define BNX2_PORT_HW_CFG_CFG_DFLT_LINK_2_5G	 0x00040000
 
 #define BNX2_PORT_HW_CFG_IMD_MAC_A_UPPER	0x00000068
 #define BNX2_PORT_HW_CFG_IMD_MAC_A_LOWER	0x0000006c
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index d2c390e..93535f0 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -453,10 +453,11 @@ struct ethtool_ops {
  * it was foced up into this mode or autonegotiated.
  */
 
-/* The forced speed, 10Mb, 100Mb, gigabit, 10GbE. */
+/* The forced speed, 10Mb, 100Mb, gigabit, 2.5Gb, 10GbE. */
 #define SPEED_10		10
 #define SPEED_100		100
 #define SPEED_1000		1000
+#define SPEED_2500		2500
 #define SPEED_10000		10000
 
 /* Duplex, half or full. */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 88de3f8..8cadfde 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1785,6 +1785,7 @@
 #define PCI_DEVICE_ID_TIGON3_5704	0x1648
 #define PCI_DEVICE_ID_TIGON3_5704S_2	0x1649
 #define PCI_DEVICE_ID_NX2_5706		0x164a
+#define PCI_DEVICE_ID_NX2_5708		0x164c
 #define PCI_DEVICE_ID_TIGON3_5702FE	0x164d
 #define PCI_DEVICE_ID_TIGON3_5705	0x1653
 #define PCI_DEVICE_ID_TIGON3_5705_2	0x1654
@@ -1809,6 +1810,7 @@
 #define PCI_DEVICE_ID_TIGON3_5703X	0x16a7
 #define PCI_DEVICE_ID_TIGON3_5704S	0x16a8
 #define PCI_DEVICE_ID_NX2_5706S		0x16aa
+#define PCI_DEVICE_ID_NX2_5708S		0x16ac
 #define PCI_DEVICE_ID_TIGON3_5702A3	0x16c6
 #define PCI_DEVICE_ID_TIGON3_5703A3	0x16c7
 #define PCI_DEVICE_ID_TIGON3_5781	0x16dd
---
0.99.8.GIT


--- NEW FILE 2460-bnx2-update-firmware-for-5708.txt ---
Subject: [PATCH] bnx2: update firmware for 5708
From: Michael Chan <mchan at broadcom.com>
Date: 1131122882 -0800

Update bnx2 firmware with support for 5708.

Signed-off-by: Michael Chan <mchan at broadcom.com>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/bnx2_fw.h | 4055 +++++++++++++++++++++++++++++++------------------
 1 files changed, 2527 insertions(+), 1528 deletions(-)

applies-to: 6a38e55a950a39a3eeae9e1fc51cac1ec4d43dce
12d30d89e57d467e4c134906a4682719813d40ad
diff --git a/drivers/net/bnx2_fw.h b/drivers/net/bnx2_fw.h
index 35f3a2a..ab07a49 100644
--- a/drivers/net/bnx2_fw.h
+++ b/drivers/net/bnx2_fw.h
@@ -14,24 +14,23 @@
  * accompanying it.
  */
 
-
-static int bnx2_COM_b06FwReleaseMajor = 0x0;
+static int bnx2_COM_b06FwReleaseMajor = 0x1;
 static int bnx2_COM_b06FwReleaseMinor = 0x0;
 static int bnx2_COM_b06FwReleaseFix = 0x0;
-static u32 bnx2_COM_b06FwStartAddr = 0x080004a0;
+static u32 bnx2_COM_b06FwStartAddr = 0x080008b4;
 static u32 bnx2_COM_b06FwTextAddr = 0x08000000;
-static int bnx2_COM_b06FwTextLen = 0x4594;
-static u32 bnx2_COM_b06FwDataAddr = 0x080045e0;
+static int bnx2_COM_b06FwTextLen = 0x57bc;
+static u32 bnx2_COM_b06FwDataAddr = 0x08005840;
 static int bnx2_COM_b06FwDataLen = 0x0;
-static u32 bnx2_COM_b06FwRodataAddr = 0x08004598;
-static int bnx2_COM_b06FwRodataLen = 0x18;
-static u32 bnx2_COM_b06FwBssAddr = 0x08004600;
+static u32 bnx2_COM_b06FwRodataAddr = 0x080057c0;
+static int bnx2_COM_b06FwRodataLen = 0x58;
+static u32 bnx2_COM_b06FwBssAddr = 0x08005860;
 static int bnx2_COM_b06FwBssLen = 0x88;
-static u32 bnx2_COM_b06FwSbssAddr = 0x080045e0;
+static u32 bnx2_COM_b06FwSbssAddr = 0x08005840;
 static int bnx2_COM_b06FwSbssLen = 0x1c;
-static u32 bnx2_COM_b06FwText[(0x4594/4) + 1] = {
-	0x0a000128, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x302e362e,
-	0x39000000, 0x00060902, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
+static u32 bnx2_COM_b06FwText[(0x57bc/4) + 1] = {
+	0x0a00022d, 0x00000000, 0x00000000, 0x0000000d, 0x636f6d20, 0x322e352e,
+	0x38000000, 0x02050802, 0x00000000, 0x00000003, 0x00000014, 0x00000032,
 	0x00000003, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000010, 0x000003e8, 0x0000ea60, 0x00000001, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
@@ -79,70 +78,117 @@ static u32 bnx2_COM_b06FwText[(0x4594/4)
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
 	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
-	0x00000000, 0x00000000, 0x00000000, 0x10000003, 0x00000000, 0x0000000d,
-	0x0000000d, 0x3c020800, 0x244245e0, 0x3c030800, 0x24634688, 0xac400000,
-	0x0043202b, 0x1480fffd, 0x24420004, 0x3c1d0800, 0x37bd7ffc, 0x03a0f021,
-	0x3c100800, 0x261004a0, 0x3c1c0800, 0x279c45e0, 0x0e0001f2, 0x00000000,
-	0x0000000d, 0x27bdffe8, 0x3c1a8000, 0x3c020008, 0x0342d825, 0x3c036010,
-	0xafbf0010, 0x8c655000, 0x3c020800, 0x24470ac8, 0x3c040800, 0x24864600,
-	0x2402ff7f, 0x00a22824, 0x34a5380c, 0xac655000, 0x00002821, 0x24020037,
-	0x24030c80, 0xaf420008, 0xaf430024, 0xacc70000, 0x24a50001, 0x2ca20016,
-	0x1440fffc, 0x24c60004, 0x24844600, 0x3c020800, 0x24420ad4, 0x3c030800,
-	0x246309d4, 0xac820004, 0x3c020800, 0x24420618, 0x3c050800, 0x24a50ca0,
-	0xac82000c, 0x3c020800, 0x24423100, 0xac830008, 0x3c030800, 0x246325c8,
-	0xac820014, 0x3c020800, 0x24422b0c, 0xac830018, 0xac83001c, 0x3c030800,
-	0x24630adc, 0xac820024, 0x3c020800, 0x24423040, 0xac83002c, 0x3c030800,
-	0x24633060, 0xac820030, 0x3c020800, 0x24422f6c, 0xac830034, 0x3c030800,
-	0x24632c60, 0xac82003c, 0x3c020800, 0x24420b6c, 0xac850010, 0xac850020,
-	0xac830040, 0x0e000bd6, 0xac820050, 0x8fbf0010, 0x03e00008, 0x27bd0018,
-	0x27bdffe0, 0xafb00010, 0x27500100, 0xafbf0018, 0xafb10014, 0x9203000b,
-	0x24020003, 0x1462005b, 0x96110008, 0x32220001, 0x10400009, 0x27430080,
-	0x8e020000, 0x96040014, 0x000211c2, 0x00021040, 0x00621821, 0xa4640000,
-	0x0a0001cb, 0x3c020800, 0x3c020800, 0x8c430020, 0x1060002a, 0x3c030800,
-	0x0e001006, 0x00000000, 0x97420108, 0x8f850018, 0x9743010c, 0x3042003e,
-	0x00021400, 0x00621825, 0xaca30000, 0x8f840018, 0x8f420100, 0xac820004,
-	0x97430116, 0x9742010e, 0x8f840018, 0x00031c00, 0x00431025, 0xac820008,
-	0x97430110, 0x97440112, 0x8f850018, 0x00031c00, 0x00832025, 0xaca4000c,
-	0x97420114, 0x8f840018, 0x3042ffff, 0xac820010, 0x8f830018, 0xac600014,
-	0x8f820018, 0x3c030800, 0xac400018, 0x9462466e, 0x8f840018, 0x3c032000,
-	0x00431025, 0xac82001c, 0x0e001044, 0x24040001, 0x3c030800, 0x8c620040,
-	0x24420001, 0xac620040, 0x3c020800, 0x8c430044, 0x32240004, 0x24630001,
-	0x10800017, 0xac430044, 0x8f4202b8, 0x04430007, 0x8e020020, 0x3c040800,
-	0x8c830060, 0x24020001, 0x24630001, 0x0a0001ed, 0xac830060, 0x3c060800,
-	0x8cc4005c, 0xaf420280, 0x96030016, 0x00001021, 0xa7430284, 0x8e050004,
-	0x24840001, 0x3c031000, 0xaf450288, 0xaf4302b8, 0x0a0001ed, 0xacc4005c,
-	0x32220002, 0x0a0001ed, 0x0002102b, 0x3c026000, 0xac400808, 0x0000000d,
-	0x00001021, 0x8fbf0018, 0x8fb10014, 0x8fb00010, 0x03e00008, 0x27bd0020,
-	0x27bdffc8, 0xafbf0034, 0xafbe0030, 0xafb7002c, 0xafb60028, 0xafb50024,
-	0xafb40020, 0xafb3001c, 0xafb20018, 0xafb10014, 0x0e00013f, 0xafb00010,
-	0x24110020, 0x24150030, 0x2794000c, 0x27930008, 0x3c124000, 0x3c1e0800,
-	0x3c170800, 0x3c160800, 0x8f820004, 0x3c040800, 0x8c830020, 0x10430004,
-	0x00000000, 0xaf830004, 0x0e00110b, 0x00000000, 0x8f500000, 0x32020007,
-	0x1040fff5, 0x32020001, 0x1040002b, 0x32020002, 0x8f420100, 0xaf420020,
-	0x8f430104, 0xaf4300a8, 0x9342010b, 0x93630000, 0x306300ff, 0x10710005,
-	0x304400ff, 0x10750006, 0x2c820016, 0x0a000227, 0x00000000, 0xaf940000,
-	0x0a000228, 0x2c820016, 0xaf930000, 0x0a000228, 0x00000000, 0xaf800000,
-	0x14400005, 0x00041880, 0x0e0002b2, 0x00000000, 0x0a000234, 0x00000000,
-	0x3c020800, 0x24424600, 0x00621821, 0x8c620000, 0x0040f809, 0x00000000,
-	0x10400005, 0x8fc20034, 0x8f420104, 0x3c016020, 0xac220014, 0x8fc20034,
-	0xaf520138, 0x24420001, 0xafc20034, 0x32020002, 0x10400019, 0x32020004,
-	0x8f420140, 0xaf420020, 0x93630000, 0x306300ff, 0x10710005, 0x00000000,
-	0x10750006, 0x00000000, 0x0a000250, 0x00000000, 0xaf940000, 0x0a000251,
-	0x00000000, 0xaf930000, 0x0a000251, 0x00000000, 0xaf800000, 0x0e0008b9,
-	0x00000000, 0x8ee20038, 0xaf520178, 0x24420001, 0xaee20038, 0x32020004,
-	0x1040ffad, 0x00000000, 0x8f420180, 0xaf420020, 0x93630000, 0x306300ff,
-	0x10710005, 0x00000000, 0x10750006, 0x00000000, 0x0a00026a, 0x00000000,
-	0xaf940000, 0x0a00026b, 0x00000000, 0xaf930000, 0x0a00026b, 0x00000000,
-	0xaf800000, 0x93620000, 0x14510004, 0x8ec2003c, 0x0e000835, 0x00000000,
-	0x8ec2003c, 0xaf5201b8, 0x24420001, 0x0a000206, 0xaec2003c, 0x27bdffe8,
-	0xafbf0010, 0x97420108, 0x24033000, 0x30447000, 0x10830012, 0x28823001,
-	0x10400007, 0x24024000, 0x1080000b, 0x24022000, 0x1082001a, 0x24020001,
-	0x0a000299, 0x00000000, 0x1082000c, 0x24025000, 0x1082000e, 0x00000000,
-	0x0a000299, 0x00000000, 0x0000000d, 0x0a00029b, 0x00001021, 0x0e000300,
-	0x00000000, 0x0a00029b, 0x00001021, 0x0e00048f, 0x00000000, 0x0a00029b,
-	0x00001021, 0x0e000fdf, 0x00000000, 0x0a00029b, 0x00001021, 0x0000000d,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000, 0x00000000,
+	0x10000003, 0x00000000, 0x0000000d, 0x0000000d, 0x3c020800, 0x24425840,
+	0x3c030800, 0x246358e8, 0xac400000, 0x0043202b, 0x1480fffd, 0x24420004,
+	0x3c1d0800, 0x37bd7ffc, 0x03a0f021, 0x3c100800, 0x261008b4, 0x3c1c0800,
+	0x279c5840, 0x0e0002f7, 0x00000000, 0x0000000d, 0x27bdffe8, 0x3c1a8000,
+	0x3c020008, 0x0342d825, 0x3c036010, 0xafbf0010, 0x8c655000, 0x3c020800,
+	0x24470f30, 0x3c040800, 0x24865860, 0x2402ff7f, 0x00a22824, 0x34a5380c,
+	0xac655000, 0x00002821, 0x24020037, 0x24030c80, 0xaf420008, 0xaf430024,
+	0xacc70000, 0x24a50001, 0x2ca20016, 0x1440fffc, 0x24c60004, 0x24845860,
+	0x3c020800, 0x24420f3c, 0x3c030800, 0x24630e2c, 0xac820004, 0x3c020800,
+	0x24420a2c, 0x3c050800, 0x24a51268, 0xac82000c, 0x3c020800, 0x244243dc,
+	0xac830008, 0x3c030800, 0x24633698, 0xac820014, 0x3c020800, 0x24423c24,
+	0xac830018, 0xac83001c, 0x3c030800, 0x24630f44, 0xac820024, 0x3c020800,
+	0x244243ac, 0xac83002c, 0x3c030800, 0x246343cc, 0xac820030, 0x3c020800,
+	0x244242f0, 0xac830034, 0x3c030800, 0x24633d78, 0xac82003c, 0x3c020800,
+	0x24420fd4, 0xac850010, 0xac850020, 0xac830040, 0x0e0010b7, 0xac820050,
+	0x8fbf0010, 0x03e00008, 0x27bd0018, 0x27bdffe0, 0xafb00010, 0x27500100,
+	0xafbf0018, 0xafb10014, 0x9203000b, 0x24020003, 0x1462005b, 0x96110008,
+	0x32220001, 0x10400009, 0x27430080, 0x8e020000, 0x96040014, 0x000211c2,
+	0x00021040, 0x00621821, 0xa4640000, 0x0a0002d0, 0x3c020800, 0x3c020800,
+	0x8c430020, 0x1060002a, 0x3c030800, 0x0e00148e, 0x00000000, 0x97420108,
+	0x8f850018, 0x9743010c, 0x3042003e, 0x00021400, 0x00621825, 0xaca30000,
+	0x8f840018, 0x8f420100, 0xac820004, 0x97430116, 0x9742010e, 0x8f840018,
+	0x00031c00, 0x00431025, 0xac820008, 0x97430110, 0x97440112, 0x8f850018,
+	0x00031c00, 0x00832025, 0xaca4000c, 0x97420114, 0x8f840018, 0x3042ffff,
+	0xac820010, 0x8f830018, 0xac600014, 0x8f820018, 0x3c030800, 0xac400018,
+	0x946258ce, 0x8f840018, 0x3c032000, 0x00431025, 0xac82001c, 0x0e0014cc,
+	0x24040001, 0x3c030800, 0x8c620040, 0x24420001, 0xac620040, 0x3c020800,
+	0x8c430044, 0x32240004, 0x24630001, 0x10800017, 0xac430044, 0x8f4202b8,
+	0x04430007, 0x8e020020, 0x3c040800, 0x8c830060, 0x24020001, 0x24630001,
+	0x0a0002f2, 0xac830060, 0x3c060800, 0x8cc4005c, 0xaf420280, 0x96030016,
+	0x00001021, 0xa7430284, 0x8e050004, 0x24840001, 0x3c031000, 0xaf450288,
+	0xaf4302b8, 0x0a0002f2, 0xacc4005c, 0x32220002, 0x0a0002f2, 0x0002102b,
+	0x3c026000, 0xac400808, 0x0000000d, 0x00001021, 0x8fbf0018, 0x8fb10014,
[...3843 lines suppressed...]
-	0xaf830020, 0x58400005, 0x8f42095c, 0x8f820000, 0xaf83001c, 0xac430054,
-	0x8f42095c, 0x31030008, 0xaf82002c, 0x1060001a, 0x00000000, 0x8f840000,
-	0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007, 0x24020007,
-	0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122, 0x8f850000,
-	0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001, 0x30630007,
-	0xac440000, 0x0a000e40, 0xa0a30120, 0x90820122, 0x34420001, 0xa0820122,
-	0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000, 0x8c43000c,
-	0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008, 0x34420001,
-	0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024, 0x1440fffd,
-	0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018, 0x00000000,
-	0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068, 0x90e40081,
-	0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b, 0x54400001,
-	0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001, 0x00c02021,
-	0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c, 0x8f830008,
-	0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f830020, 0x3c020800,
-	0x24504120, 0xae030024, 0x8ee20010, 0x0040f809, 0x00000000, 0x12a00005,
-	0x00000000, 0x8f420e10, 0xae02002c, 0x8f430e18, 0xae030030, 0x1220feba,
-	0x0000a821, 0x8f870024, 0x97860028, 0x8f830000, 0x8f820030, 0x8f840020,
-	0x8f85001c, 0x32500040, 0xa4e6002c, 0xac620044, 0x32420008, 0xac640050,
-	0xac650054, 0x1040007a, 0x32820020, 0x10400027, 0x32910010, 0x24072000,
-	0x3c090800, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec2414c,
-	0x26c4414c, 0x2484ffd4, 0xaf420144, 0x8c820030, 0x3c030400, 0xaf420148,
-	0x24020041, 0xaf43014c, 0x00001821, 0xa3420152, 0x3c021000, 0xa7430158,
-	0xaf470154, 0xaf420178, 0x8ec5414c, 0x8d230030, 0x8c860030, 0x24630001,
-	0xad230030, 0x93420109, 0x9343010a, 0xafa70014, 0xafa00018, 0x00021600,
-	0x00031c00, 0x00431025, 0x34424100, 0xafa20010, 0x8f440100, 0x0e000fe1,
-	0x3c070400, 0x12200028, 0x24072000, 0x3c090800, 0x3c038000, 0x8f420178,
-	0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144,
-	0x8c820030, 0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0x00001821,
-	0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c,
-	0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a,
-	0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424e00,
-	0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070300, 0x0a000f0b, 0x8fa30024,
-	0x32820008, 0x10400026, 0x3c090800, 0x24072000, 0x3c038000, 0x8f420178,
-	0x00431024, 0x1440fffd, 0x8ec2414c, 0x26c4414c, 0x2484ffd4, 0xaf420144,
-	0x8c820030, 0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0x00001821,
-	0xa3420152, 0x3c021000, 0xa7430158, 0xaf470154, 0xaf420178, 0x8ec5414c,
-	0x8d230030, 0x8c860030, 0x24630001, 0xad230030, 0x93420109, 0x9343010a,
-	0xafa70014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025, 0x34424b00,
-	0xafa20010, 0x8f440100, 0x0e000fe1, 0x3c070200, 0x8fa30024, 0x14600004,
-	0x8fa40020, 0x32420010, 0x10400004, 0x00000000, 0x8c820004, 0x0040f809,
-	0x00000000, 0x12000006, 0x8fa30020, 0x8c620008, 0x0040f809, 0x00000000,
-	0x0a000f4d, 0x8fbf004c, 0x3c030800, 0x8c62413c, 0x30420040, 0x1440002f,
-	0x8fbf004c, 0x24040040, 0x8f910020, 0x3c038000, 0x8f420178, 0x00431024,
-	0x1440fffd, 0x8ec2414c, 0x26d0414c, 0x2610ffd4, 0xaf420144, 0x8e020030,
-	0x00001821, 0xaf420148, 0x24020049, 0xaf51014c, 0xa3420152, 0x3c021000,
-	0xa7430158, 0xaf440154, 0xaf420178, 0x8ec5414c, 0x8e060030, 0x93420109,
-	0x9343010a, 0xafa40014, 0xafa00018, 0x00021600, 0x00031c00, 0x00431025,
-	0x34424900, 0xafa20010, 0x8f440100, 0x0e000fe1, 0x02203821, 0x8f830000,
-	0x8e020030, 0x8c64017c, 0x02221023, 0x00441023, 0x2c420002, 0x14400005,
-	0x8fbf004c, 0x0000000d, 0x00000000, 0x240000ca, 0x8fbf004c, 0x8fbe0048,
-	0x8fb70044, 0x8fb60040, 0x8fb5003c, 0x8fb40038, 0x8fb30034, 0x8fb20030,
-	0x8fb1002c, 0x8fb00028, 0x03e00008, 0x27bd0050, 0x03e00008, 0x00001021,
-	0x3c030800, 0x24654120, 0x8ca40004, 0x8c634120, 0x0064102b, 0x54400001,
-	0x00602021, 0x9743093c, 0x0083102b, 0x54400001, 0x00801821, 0x00001021,
-	0xaca30008, 0x03e00008, 0xa4a00022, 0x8f850004, 0x97840010, 0x3c030800,
-	0x24634120, 0x24020008, 0xa462000e, 0x8f820004, 0xa460000c, 0x000420c2,
+	0x3c040800, 0x24865880, 0x94c20010, 0x94c3001a, 0x8cc40008, 0x00432821,
+	0x14800006, 0xa4c5001c, 0x3c020800, 0x8c430048, 0x10600002, 0x24a20040,
+	0xa4c2001c, 0x27d05880, 0x9604001c, 0x96020012, 0x00822021, 0x24840002,
+	0x0e000faf, 0x3084ffff, 0x8f850018, 0x00a01821, 0xa2030025, 0x8ee60008,
+	0x00402021, 0x24a50001, 0xaf850018, 0x00c0f809, 0x00000000, 0x00402021,
+	0x0e001026, 0x02202821, 0x8ee3000c, 0x0060f809, 0x00402021, 0x9604001c,
+	0x96020012, 0x00822021, 0x24840002, 0x0e000fc5, 0x3084ffff, 0x8fc25880,
+	0x8e030008, 0x00431023, 0x14400012, 0xafc25880, 0x54600006, 0x8e020020,
+	0x3243004a, 0x24020002, 0x14620005, 0x00000000, 0x8e020020, 0x34420040,
+	0x0a001382, 0xae020020, 0x52a00006, 0x36520002, 0x8e020030, 0xaf420e10,
+	0x8e030034, 0xaf430e18, 0x36520002, 0x52a00008, 0x96670014, 0x8f830000,
+	0x8f420e10, 0xac6200a8, 0x8f840000, 0x8f420e18, 0xac8200ac, 0x96670014,
+	0x92680024, 0x24020040, 0xaf420814, 0x8f830020, 0x8f82001c, 0x00671821,
+	0x00621023, 0xaf830020, 0x18400008, 0x00000000, 0x8f820000, 0xaf83001c,
+	0xac430054, 0x54e00005, 0xaf400040, 0x0a0013a0, 0x8f42095c, 0x54e00001,
+	0xaf400044, 0x8f42095c, 0x31030008, 0xaf820030, 0x1060001a, 0x00000000,
+	0x8f840000, 0x90820120, 0x90830121, 0x304600ff, 0x00c31823, 0x30630007,
+	0x24020007, 0x1062000e, 0x00000000, 0x90820122, 0x304200fe, 0xa0820122,
+	0x8f850000, 0x00061880, 0x8f840020, 0x24a20100, 0x00431021, 0x24c30001,
+	0x30630007, 0xac440000, 0x0a0013bd, 0xa0a30120, 0x90820122, 0x34420001,
+	0xa0820122, 0x14e00003, 0x31020001, 0x10400031, 0x32510002, 0x8f820000,
+	0x8c43000c, 0x30630001, 0x1060002c, 0x32510002, 0x3c029000, 0x8f830008,
+	0x34420001, 0x3c048000, 0x00621825, 0xaf430020, 0x8f420020, 0x00441024,
+	0x1440fffd, 0x00000000, 0x8f870000, 0x8ce2000c, 0x30420001, 0x10400018,
+	0x00000000, 0x94e2006a, 0x00022880, 0x50a00001, 0x24050001, 0x94e30068,
+	0x90e40081, 0x3c020800, 0x8c460024, 0x00652821, 0x00852804, 0x00c5102b,
+	0x54400001, 0x00a03021, 0x3c020800, 0x8c440028, 0x00c4182b, 0x54600001,
+	0x00c02021, 0x8f430074, 0x2402fffe, 0x00822824, 0x00a31821, 0xace3000c,
+	0x8f830008, 0x3c028000, 0x34420001, 0x00621825, 0xaf430020, 0x8f820020,
+	0x3c050800, 0x24b05880, 0xae020028, 0x8ee30010, 0x0060f809, 0x00000000,
+	0x8f820028, 0x24420001, 0xaf820028, 0x12a00005, 0xaf40004c, 0x8f420e10,
+	0xae020030, 0x8f430e18, 0xae030034, 0x1220fea7, 0x24020006, 0x8f870024,
+	0x9786002c, 0x8f830000, 0x8f820034, 0x8f840020, 0x8f85001c, 0x32530040,
+	0xa4e6002c, 0xac620044, 0x32420008, 0xac640050, 0xac650054, 0x1040007a,
+	0x32820020, 0x10400027, 0x32910010, 0x00003821, 0x24052000, 0x3c090800,
+	0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd, 0x8ec258b0, 0x26c458b0,
+	0x2484ffd0, 0xaf420144, 0x8c820034, 0x3c030400, 0xaf420148, 0x24020041,
+	0xaf43014c, 0xa3420152, 0x8d230030, 0x3c021000, 0xa7470158, 0xaf450154,
+	0xaf420178, 0x8c860034, 0x24630001, 0xad230030, 0x9342010a, 0x3c030041,
+	0xafa50014, 0x00021600, 0x00431025, 0x00471025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x3c070400, 0x12200028,
+	0x00003821, 0x24052000, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
+	0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
+	0x3c030300, 0xaf420148, 0x2402004e, 0xaf43014c, 0xa3420152, 0x8d230030,
+	0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
+	0xad230030, 0x9342010a, 0x3c03004e, 0xafa50014, 0x00021600, 0x00431025,
+	0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
+	0x0e00159b, 0x3c070300, 0x0a00148b, 0x8fa20024, 0x32820008, 0x10400026,
+	0x24052000, 0x00003821, 0x3c090800, 0x3c038000, 0x8f420178, 0x00431024,
+	0x1440fffd, 0x8ec258b0, 0x26c458b0, 0x2484ffd0, 0xaf420144, 0x8c820034,
+	0x3c030200, 0xaf420148, 0x2402004b, 0xaf43014c, 0xa3420152, 0x8d230030,
+	0x3c021000, 0xa7470158, 0xaf450154, 0xaf420178, 0x8c860034, 0x24630001,
+	0xad230030, 0x9342010a, 0x3c03004b, 0xafa50014, 0x00021600, 0x00431025,
+	0x00471025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100, 0x8f450104,
+	0x0e00159b, 0x3c070200, 0x8fa20024, 0x14400004, 0x8fa30020, 0x32420010,
+	0x10400004, 0x00000000, 0x8c620004, 0x0040f809, 0x00000000, 0x12600006,
+	0x8fa40020, 0x8c820008, 0x0040f809, 0x00000000, 0x0a0014c1, 0x8fbf0054,
+	0x3c030800, 0x8c6258a0, 0x30420040, 0x14400023, 0x8fbf0054, 0x00002821,
+	0x24040040, 0x8f870020, 0x3c038000, 0x8f420178, 0x00431024, 0x1440fffd,
+	0x8ec258b0, 0x26c358b0, 0x2463ffd0, 0xaf420144, 0x8c620034, 0xaf420148,
+	0x24020049, 0xaf47014c, 0xa3420152, 0x3c021000, 0xa7450158, 0xaf440154,
+	0xaf420178, 0x8c660034, 0x9342010a, 0x3c030049, 0xafa40014, 0x00021600,
+	0x00431025, 0x00451025, 0xafa20010, 0x9343010b, 0xafa30018, 0x8f440100,
+	0x0e00159b, 0x8f450104, 0x8fbf0054, 0x8fbe0050, 0x8fb7004c, 0x8fb60048,
+	0x8fb50044, 0x8fb40040, 0x8fb3003c, 0x8fb20038, 0x8fb10034, 0x8fb00030,
+	0x03e00008, 0x27bd0058, 0x03e00008, 0x00001021, 0x3c020800, 0x24435880,
+	0x8c650004, 0x8c445880, 0x0085182b, 0x10600002, 0x00403021, 0x00802821,
+	0x9744093c, 0x00a4102b, 0x54400001, 0x00a02021, 0x93420923, 0x0004182b,
+	0x00021042, 0x30420001, 0x00431024, 0x1040000d, 0x24c25880, 0x8f850000,
+	0x8f830020, 0x8ca20084, 0x00431023, 0x04420007, 0x24c25880, 0x8ca20084,
+	0x00641821, 0x00431023, 0x28420001, 0x00822023, 0x24c25880, 0xac440008,
+	0xa4400026, 0x03e00008, 0x00001021, 0x8f850004, 0x97840010, 0x3c030800,
+	0x24635880, 0x24020008, 0xa4620012, 0x8f820004, 0xa4600010, 0x000420c2,
 	0x30840008, 0x2c420001, 0x00021023, 0x30420006, 0xac650008, 0x03e00008,
-	0xa0640020, 0x3c020800, 0x24424120, 0x90450021, 0x94430018, 0x3c021100,
+	0xa0640024, 0x3c020800, 0x24425880, 0x90450025, 0x9443001c, 0x3c021100,
 	0xac800004, 0x00052c00, 0x24630002, 0x00621825, 0x00a32825, 0x24820008,
-	0x03e00008, 0xac850000, 0x0000000d, 0x00000000, 0x2400016f, 0x03e00008,
-	0x00000000, 0x0000000d, 0x00000000, 0x2400017b, 0x03e00008, 0x00000000,
-	0x03e00008, 0x00000000, 0x3c020800, 0x24424120, 0xac400008, 0xa4400022,
-	0x03e00008, 0x24020001, 0x3c020800, 0x24424120, 0x24030008, 0xac400008,
-	0xa440000c, 0xa443000e, 0xa0400020, 0x03e00008, 0x24020004, 0x03e00008,
+	0x03e00008, 0xac850000, 0x27bdffd8, 0x3c020800, 0x24425880, 0xafbf0020,
+	0x90480025, 0x8c440008, 0x8c460020, 0x8f870020, 0x3c030800, 0x3c058000,
+	0x8f420178, 0x00451024, 0x1440fffd, 0x8c6258b0, 0x246358b0, 0x2469ffd0,
+	0xaf420144, 0x8d220034, 0x30c32000, 0xaf420148, 0x3c021000, 0xaf47014c,
+	0xa3480152, 0xa7440158, 0xaf460154, 0xaf420178, 0x10600004, 0x3c030800,
+	0x8c620030, 0x24420001, 0xac620030, 0x9342010a, 0x00081c00, 0x3084ffff,
+	0xafa60014, 0x00021600, 0x00431025, 0x00441025, 0xafa20010, 0x9343010b,
+	0xafa30018, 0x8f440100, 0x8f450104, 0x0e00159b, 0x8d260034, 0x8fbf0020,
+	0x03e00008, 0x27bd0028, 0x0000000d, 0x00000000, 0x2400019d, 0x03e00008,
+	0x00000000, 0x0000000d, 0x00000000, 0x240001a9, 0x03e00008, 0x00000000,
+	0x03e00008, 0x00000000, 0x3c020800, 0x24425880, 0xac400008, 0xa4400026,
+	0x03e00008, 0x24020001, 0x3c020800, 0x24425880, 0x24030008, 0xac400008,
+	0xa4400010, 0xa4430012, 0xa0400024, 0x03e00008, 0x24020004, 0x03e00008,
 	0x00001021, 0x10c00007, 0x00000000, 0x8ca20000, 0x24c6ffff, 0x24a50004,
-	0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a000fb2,
-	0x00a01021, 0xac860000, 0x24840004, 0x00a01021, 0x1440fffc, 0x24a5ffff,
-	0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068, 0x3c050800, 0x24a51090,
-	0x00093140, 0x00c51021, 0xac440000, 0x8f440e04, 0x00a61021, 0xac440004,
-	0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00, 0x00431025, 0xac820008,
-	0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14, 0xac440010, 0x8f430e18,
-	0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff, 0x25290001, 0xac470018,
-	0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000, 0x24630001, 0xace3006c,
-	0x8c434448, 0x3129007f, 0x00a62821, 0xad490068, 0x00042600, 0x00681824,
-	0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010, 0x8fad0014, 0x8fae0018,
-	0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080078, 0x000a4940, 0x01281021,
-	0x01091821, 0xac440000, 0x00601021, 0xac650004, 0xac460008, 0xac67000c,
-	0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018, 0x8c654448, 0x3c040800,
-	0x8c820064, 0x254a0001, 0x314a007f, 0x01094021, 0xad6a0060, 0x24420001,
-	0xac820064, 0x03e00008, 0xad05001c, 0x00000000 };
-
-static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x00000000 };
-static u32 bnx2_TXP_b06FwBss[(0x194/4) + 1] = { 0x00000000 };
-static u32 bnx2_TXP_b06FwSbss[(0x34/4) + 1] = { 0x00000000 };
+	0xac820000, 0x14c0fffb, 0x24840004, 0x03e00008, 0x00000000, 0x0a00156c,
+	0x00a01021, 0xac860000, 0x00000000, 0x00000000, 0x24840004, 0x00a01021,
+	0x1440fffa, 0x24a5ffff, 0x03e00008, 0x00000000, 0x3c0a0800, 0x8d490068,
+	0x3c050800, 0x24a52098, 0x00093140, 0x00c51021, 0xac440000, 0x8f440e04,
+	0x00a61021, 0xac440004, 0x97430e08, 0x97420e0c, 0x00a62021, 0x00031c00,
+	0x00431025, 0xac820008, 0x8f430e10, 0x00801021, 0xac43000c, 0x8f440e14,
+	0xac440010, 0x8f430e18, 0x3c0800ff, 0xac430014, 0x8f470e1c, 0x3508ffff,
+	0x25290001, 0xac470018, 0x3c070800, 0x8ce3006c, 0x9344010a, 0x3c026000,
+	0x24630001, 0xace3006c, 0x8c434448, 0x3129007f, 0x00a62821, 0xad490068,
+	0x00042600, 0x00681824, 0x00832025, 0x03e00008, 0xaca4001c, 0x8fac0010,
+	0x8fad0014, 0x8fae0018, 0x3c0b0800, 0x8d6a0060, 0x3c080800, 0x25080080,
+	0x000a4940, 0x01281021, 0x01091821, 0xac440000, 0x00601021, 0xac650004,
+	0xac460008, 0xac67000c, 0xac4c0010, 0xac6d0014, 0x3c036000, 0xac4e0018,
+	0x8c654448, 0x3c040800, 0x8c820064, 0x254a0001, 0x314a00ff, 0x01094021,
+	0xad6a0060, 0x24420001, 0xac820064, 0x03e00008, 0xad05001c, 0x3c030800,
+	0x3c090800, 0x8d250070, 0x246330b0, 0x8f460100, 0x00053900, 0x00e31021,
+	0xac460000, 0x8f440104, 0x00671021, 0xac440004, 0x8f460108, 0x8f840014,
+	0x24a50001, 0xac460008, 0x8c880074, 0x3c060800, 0x8cc20074, 0x30a5003f,
+	0x00671821, 0xad250070, 0x24420001, 0xacc20074, 0x03e00008, 0xac68000c,
+	0x00000000 };
 
+static u32 bnx2_TXP_b06FwData[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwRodata[(0x0/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwBss[(0x1c4/4) + 1] = { 0x0 };
+static u32 bnx2_TXP_b06FwSbss[(0x38/4) + 1] = { 0x0 };
---
0.99.8.GIT


--- NEW FILE 2461-bnx2-update-nvram-code-for-5708.txt ---
Subject: [PATCH] bnx2: update nvram code for 5708
From: Michael Chan <mchan at broadcom.com>
Date: 1131122957 -0800

Update bnx2 nvram code with support for 5708.

Signed-off-by: Michael Chan <mchan at broadcom.com>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/bnx2.c |  100 +++++++++++++++++++++++++++++++++++++++++-----------
 drivers/net/bnx2.h |   10 +++++
 2 files changed, 87 insertions(+), 23 deletions(-)

applies-to: e62914ff479d1b5273936bcb56cc3b28e2b5cbcb
371377091dff14090cbe995d0a9291364f8583cb
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 671393a..08086a9 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -79,38 +79,88 @@ static struct pci_device_id bnx2_pci_tbl
 static struct flash_spec flash_table[] =
 {
 	/* Slow EEPROM */
-	{0x00000000, 0x40030380, 0x009f0081, 0xa184a053, 0xaf000400,
+	{0x00000000, 0x40830380, 0x009f0081, 0xa184a053, 0xaf000400,
 	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
 	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
 	 "EEPROM - slow"},
-	/* Fast EEPROM */
-	{0x02000000, 0x62008380, 0x009f0081, 0xa184a053, 0xaf000400,
-	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
-	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
-	 "EEPROM - fast"},
-	/* ATMEL AT45DB011B (buffered flash) */
-	{0x02000003, 0x6e008173, 0x00570081, 0x68848353, 0xaf000400,
-	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
-	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
-	 "Buffered flash"},
-	/* Saifun SA25F005 (non-buffered flash) */
-       	/* strap, cfg1, & write1 need updates */
-	{0x01000003, 0x5f008081, 0x00050081, 0x03840253, 0xaf020406,
+	/* Expansion entry 0001 */
+	{0x08000002, 0x4b808201, 0x00050081, 0x03840253, 0xaf020406,
 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
-	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
-	 "Non-buffered flash (64kB)"},
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 0001"},
 	/* Saifun SA25F010 (non-buffered flash) */
 	/* strap, cfg1, & write1 need updates */
-	{0x00000001, 0x47008081, 0x00050081, 0x03840253, 0xaf020406,
+	{0x04000001, 0x47808201, 0x00050081, 0x03840253, 0xaf020406,
 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*2,
 	 "Non-buffered flash (128kB)"},
 	/* Saifun SA25F020 (non-buffered flash) */
 	/* strap, cfg1, & write1 need updates */
-	{0x00000003, 0x4f008081, 0x00050081, 0x03840253, 0xaf020406,
+	{0x0c000003, 0x4f808201, 0x00050081, 0x03840253, 0xaf020406,
 	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
 	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE*4,
 	 "Non-buffered flash (256kB)"},
+	/* Expansion entry 0100 */
+	{0x11000000, 0x53808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 0100"},
+	/* Entry 0101: ST M45PE10 (non-buffered flash, TetonII B0) */
+	{0x19000002, 0x5b808201, 0x000500db, 0x03840253, 0xaf020406,        
+	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
+	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*2,
+	 "Entry 0101: ST M45PE10 (128kB non-bufferred)"},
+	/* Entry 0110: ST M45PE20 (non-buffered flash)*/
+	{0x15000001, 0x57808201, 0x000500db, 0x03840253, 0xaf020406,
+	 0, ST_MICRO_FLASH_PAGE_BITS, ST_MICRO_FLASH_PAGE_SIZE,
+	 ST_MICRO_FLASH_BYTE_ADDR_MASK, ST_MICRO_FLASH_BASE_TOTAL_SIZE*4,
+	 "Entry 0110: ST M45PE20 (256kB non-bufferred)"},
+	/* Saifun SA25F005 (non-buffered flash) */
+	/* strap, cfg1, & write1 need updates */
+	{0x1d000003, 0x5f808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, SAIFUN_FLASH_BASE_TOTAL_SIZE,
+	 "Non-buffered flash (64kB)"},
+	/* Fast EEPROM */
+	{0x22000000, 0x62808380, 0x009f0081, 0xa184a053, 0xaf000400,
+	 1, SEEPROM_PAGE_BITS, SEEPROM_PAGE_SIZE,
+	 SEEPROM_BYTE_ADDR_MASK, SEEPROM_TOTAL_SIZE,
+	 "EEPROM - fast"},
+	/* Expansion entry 1001 */
+	{0x2a000002, 0x6b808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1001"},
+	/* Expansion entry 1010 */
+	{0x26000001, 0x67808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1010"},
+	/* ATMEL AT45DB011B (buffered flash) */
+	{0x2e000003, 0x6e808273, 0x00570081, 0x68848353, 0xaf000400,
+	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE,
+	 "Buffered flash (128kB)"},
+	/* Expansion entry 1100 */
+	{0x33000000, 0x73808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1100"},
+	/* Expansion entry 1101 */
+	{0x3b000002, 0x7b808201, 0x00050081, 0x03840253, 0xaf020406,
+	 0, SAIFUN_FLASH_PAGE_BITS, SAIFUN_FLASH_PAGE_SIZE,
+	 SAIFUN_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1101"},
+	/* Ateml Expansion entry 1110 */
+	{0x37000001, 0x76808273, 0x00570081, 0x68848353, 0xaf000400,
+	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+	 BUFFERED_FLASH_BYTE_ADDR_MASK, 0,
+	 "Entry 1110 (Atmel)"},
+	/* ATMEL AT45DB021B (buffered flash) */
+	{0x3f000003, 0x7e808273, 0x00570081, 0x68848353, 0xaf000400,
+	 1, BUFFERED_FLASH_PAGE_BITS, BUFFERED_FLASH_PAGE_SIZE,
+	 BUFFERED_FLASH_BYTE_ADDR_MASK, BUFFERED_FLASH_TOTAL_SIZE*2,
+	 "Buffered flash (256kB)"},
 };
 
 MODULE_DEVICE_TABLE(pci, bnx2_pci_tbl);
@@ -2529,21 +2579,27 @@ bnx2_init_nvram(struct bnx2 *bp)
 
 		/* Flash interface has been reconfigured */
 		for (j = 0, flash = &flash_table[0]; j < entry_count;
-			j++, flash++) {
-
-			if (val == flash->config1) {
+		     j++, flash++) {
+			if ((val & FLASH_BACKUP_STRAP_MASK) ==
+			    (flash->config1 & FLASH_BACKUP_STRAP_MASK)) {
 				bp->flash_info = flash;
 				break;
 			}
 		}
 	}
 	else {
+		u32 mask;
 		/* Not yet been reconfigured */
 
+		if (val & (1 << 23))
+			mask = FLASH_BACKUP_STRAP_MASK;
+		else
+			mask = FLASH_STRAP_MASK;
+
 		for (j = 0, flash = &flash_table[0]; j < entry_count;
 			j++, flash++) {
 
-			if ((val & FLASH_STRAP_MASK) == flash->strapping) {
+			if ((val & mask) == (flash->strapping & mask)) {
 				bp->flash_info = flash;
 
 				/* Request access to the flash interface. */
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index c0e88f8..4a2e6ba 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -3847,7 +3847,7 @@ struct sw_bd {
 #define BUFFERED_FLASH_PHY_PAGE_SIZE		(1 << BUFFERED_FLASH_PAGE_BITS)
 #define BUFFERED_FLASH_BYTE_ADDR_MASK		(BUFFERED_FLASH_PHY_PAGE_SIZE-1)
 #define BUFFERED_FLASH_PAGE_SIZE		264
-#define BUFFERED_FLASH_TOTAL_SIZE		131072
+#define BUFFERED_FLASH_TOTAL_SIZE		0x21000
 
 #define SAIFUN_FLASH_PAGE_BITS			8
 #define SAIFUN_FLASH_PHY_PAGE_SIZE		(1 << SAIFUN_FLASH_PAGE_BITS)
@@ -3855,6 +3855,12 @@ struct sw_bd {
 #define SAIFUN_FLASH_PAGE_SIZE			256
 #define SAIFUN_FLASH_BASE_TOTAL_SIZE		65536
 
+#define ST_MICRO_FLASH_PAGE_BITS		8
+#define ST_MICRO_FLASH_PHY_PAGE_SIZE		(1 << ST_MICRO_FLASH_PAGE_BITS)
+#define ST_MICRO_FLASH_BYTE_ADDR_MASK		(ST_MICRO_FLASH_PHY_PAGE_SIZE-1)
+#define ST_MICRO_FLASH_PAGE_SIZE		256
+#define ST_MICRO_FLASH_BASE_TOTAL_SIZE		65536
+
 #define NVRAM_TIMEOUT_COUNT			30000
 
 
@@ -3863,6 +3869,8 @@ struct sw_bd {
 						 BNX2_NVM_CFG1_PROTECT_MODE | \
 						 BNX2_NVM_CFG1_FLASH_SIZE)
 
+#define FLASH_BACKUP_STRAP_MASK			(0xf << 26)
+
 struct flash_spec {
 	u32 strapping;
 	u32 config1;
---
0.99.8.GIT


--- NEW FILE 2462-bnx2-update-firmware-handshake-for-5708.txt ---
Subject: [PATCH] bnx2: update firmware handshake for 5708
From: Michael Chan <mchan at broadcom.com>
Date: 1131123081 -0800

Dynamically determine the shared memory location where eeprom
parameters are stored instead of using a fixed location.

Add speed reporting to management firmware. This allows management
firmware to know the current speed without contending for MII
registers.

Signed-off-by: Michael Chan <mchan at broadcom.com>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/bnx2.c |   94 ++++++++++++++++++++++++++++++++++++++++++++--------
 drivers/net/bnx2.h |   43 ++++++++++++++++++++++++
 2 files changed, 122 insertions(+), 15 deletions(-)

applies-to: db98dbad7e594438434963a5e28e05dae67c61ee
e3648b3d8de3b37fae7acbb57db1e001a19cd3b7
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index 08086a9..affb673 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -437,6 +437,62 @@ alloc_mem_err:
 }
 
 static void
+bnx2_report_fw_link(struct bnx2 *bp)
+{
+	u32 fw_link_status = 0;
+
+	if (bp->link_up) {
+		u32 bmsr;
+
+		switch (bp->line_speed) {
+		case SPEED_10:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_10HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_10FULL;
+			break;
+		case SPEED_100:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_100HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_100FULL;
+			break;
+		case SPEED_1000:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_1000HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_1000FULL;
+			break;
+		case SPEED_2500:
+			if (bp->duplex == DUPLEX_HALF)
+				fw_link_status = BNX2_LINK_STATUS_2500HALF;
+			else
+				fw_link_status = BNX2_LINK_STATUS_2500FULL;
+			break;
+		}
+
+		fw_link_status |= BNX2_LINK_STATUS_LINK_UP;
+
+		if (bp->autoneg) {
+			fw_link_status |= BNX2_LINK_STATUS_AN_ENABLED;
+
+			bnx2_read_phy(bp, MII_BMSR, &bmsr);
+			bnx2_read_phy(bp, MII_BMSR, &bmsr);
+
+			if (!(bmsr & BMSR_ANEGCOMPLETE) ||
+			    bp->phy_flags & PHY_PARALLEL_DETECT_FLAG)
+				fw_link_status |= BNX2_LINK_STATUS_PARALLEL_DET;
+			else
+				fw_link_status |= BNX2_LINK_STATUS_AN_COMPLETE;
+		}
+	}
+	else
+		fw_link_status = BNX2_LINK_STATUS_LINK_DOWN;
+
+	REG_WR_IND(bp, bp->shmem_base + BNX2_LINK_STATUS, fw_link_status);
+}
+
+static void
 bnx2_report_link(struct bnx2 *bp)
 {
 	if (bp->link_up) {
@@ -467,6 +523,8 @@ bnx2_report_link(struct bnx2 *bp)
 		netif_carrier_off(bp->dev);
 		printk(KERN_ERR PFX "%s NIC Link is Down\n", bp->dev->name);
 	}
+
+	bnx2_report_fw_link(bp);
 }
 
 static void
@@ -1123,13 +1181,13 @@ bnx2_init_5708s_phy(struct bnx2 *bp)
 		bnx2_write_phy(bp, BCM5708S_BLK_ADDR, BCM5708S_BLK_ADDR_DIG);
 	}
 
-	val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_CONFIG) &
+	val = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG) &
 	      BNX2_PORT_HW_CFG_CFG_TXCTL3_MASK;
 
 	if (val) {
 		u32 is_backplane;
 
-		is_backplane = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
+		is_backplane = REG_RD_IND(bp, bp->shmem_base +
 					  BNX2_SHARED_HW_CFG_CONFIG);
 		if (is_backplane & BNX2_SHARED_HW_CFG_PHY_BACKPLANE) {
 			bnx2_write_phy(bp, BCM5708S_BLK_ADDR,
@@ -1280,13 +1338,13 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_da
 	bp->fw_wr_seq++;
 	msg_data |= bp->fw_wr_seq;
 
-	REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
+	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
 
 	/* wait for an acknowledgement. */
 	for (i = 0; i < (FW_ACK_TIME_OUT_MS * 1000)/5; i++) {
 		udelay(5);
 
-		val = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_FW_MB);
+		val = REG_RD_IND(bp, bp->shmem_base + BNX2_FW_MB);
 
 		if ((val & BNX2_FW_MSG_ACK) == (msg_data & BNX2_DRV_MSG_SEQ))
 			break;
@@ -1299,7 +1357,7 @@ bnx2_fw_sync(struct bnx2 *bp, u32 msg_da
 		msg_data &= ~BNX2_DRV_MSG_CODE;
 		msg_data |= BNX2_DRV_MSG_CODE_FW_TIMEOUT;
 
-		REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_MB, msg_data);
+		REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_MB, msg_data);
 
 		bp->fw_timed_out = 1;
 
@@ -2935,7 +2993,7 @@ bnx2_reset_chip(struct bnx2 *bp, u32 res
 
 	/* Deposit a driver reset signature so the firmware knows that
 	 * this is a soft reset. */
-	REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_RESET_SIGNATURE,
+	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_RESET_SIGNATURE,
 		   BNX2_DRV_RESET_SIGNATURE_MAGIC);
 
 	bp->fw_timed_out = 0;
@@ -4012,7 +4070,7 @@ bnx2_timer(unsigned long data)
 		goto bnx2_restart_timer;
 
 	msg = (u32) ++bp->fw_drv_pulse_wr_seq;
-	REG_WR_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DRV_PULSE_MB, msg);
+	REG_WR_IND(bp, bp->shmem_base + BNX2_DRV_PULSE_MB, msg);
 
 	if ((bp->phy_flags & PHY_SERDES_FLAG) &&
 	    (CHIP_NUM(bp) == CHIP_NUM_5706)) {
@@ -5483,10 +5541,18 @@ bnx2_init_board(struct pci_dev *pdev, st
 
 	bnx2_init_nvram(bp);
 
+	reg = REG_RD_IND(bp, BNX2_SHM_HDR_SIGNATURE);
+
+	if ((reg & BNX2_SHM_HDR_SIGNATURE_SIG_MASK) ==
+	    BNX2_SHM_HDR_SIGNATURE_SIG)
+		bp->shmem_base = REG_RD_IND(bp, BNX2_SHM_HDR_ADDR_0);
+	else
+		bp->shmem_base = HOST_VIEW_SHMEM_BASE;
+
 	/* Get the permanent MAC address.  First we need to make sure the
 	 * firmware is actually running.
 	 */
-	reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_DEV_INFO_SIGNATURE);
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_SIGNATURE);
 
 	if ((reg & BNX2_DEV_INFO_SIGNATURE_MAGIC_MASK) !=
 	    BNX2_DEV_INFO_SIGNATURE_MAGIC) {
@@ -5495,14 +5561,13 @@ bnx2_init_board(struct pci_dev *pdev, st
 		goto err_out_unmap;
 	}
 
-	bp->fw_ver = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
-				BNX2_DEV_INFO_BC_REV);
+	bp->fw_ver = REG_RD_IND(bp, bp->shmem_base + BNX2_DEV_INFO_BC_REV);
 
-	reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_UPPER);
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_UPPER);
 	bp->mac_addr[0] = (u8) (reg >> 8);
 	bp->mac_addr[1] = (u8) reg;
 
-	reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE + BNX2_PORT_HW_CFG_MAC_LOWER);
+	reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_MAC_LOWER);
 	bp->mac_addr[2] = (u8) (reg >> 24);
 	bp->mac_addr[3] = (u8) (reg >> 16);
 	bp->mac_addr[4] = (u8) (reg >> 8);
@@ -5538,7 +5603,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 		bp->flags |= NO_WOL_FLAG;
 		if (CHIP_NUM(bp) == CHIP_NUM_5708) {
 			bp->phy_addr = 2;
-			reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
+			reg = REG_RD_IND(bp, bp->shmem_base +
 					 BNX2_SHARED_HW_CFG_CONFIG);
 			if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G)
 				bp->phy_flags |= PHY_2_5G_CAPABLE_FLAG;
@@ -5562,8 +5627,7 @@ bnx2_init_board(struct pci_dev *pdev, st
 	if (bp->phy_flags & PHY_SERDES_FLAG) {
 		bp->advertising = ETHTOOL_ALL_FIBRE_SPEED | ADVERTISED_Autoneg;
 
-		reg = REG_RD_IND(bp, HOST_VIEW_SHMEM_BASE +
-				 BNX2_PORT_HW_CFG_CONFIG);
+		reg = REG_RD_IND(bp, bp->shmem_base + BNX2_PORT_HW_CFG_CONFIG);
 		reg &= BNX2_PORT_HW_CFG_CFG_DFLT_LINK_MASK;
 		if (reg == BNX2_PORT_HW_CFG_CFG_DFLT_LINK_1G) {
 			bp->autoneg = 0;
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 4a2e6ba..012586e 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -3715,6 +3715,15 @@ struct l2_fhdr {
 #define BNX2_MCP_ROM					0x00150000
 #define BNX2_MCP_SCRATCH				0x00160000
 
+#define BNX2_SHM_HDR_SIGNATURE				BNX2_MCP_SCRATCH
+#define BNX2_SHM_HDR_SIGNATURE_SIG_MASK			 0xffff0000
+#define BNX2_SHM_HDR_SIGNATURE_SIG			 0x53530000
+#define BNX2_SHM_HDR_SIGNATURE_VER_MASK			 0x000000ff
+#define BNX2_SHM_HDR_SIGNATURE_VER_ONE			 0x00000001
+
+#define BNX2_SHM_HDR_ADDR_0				BNX2_MCP_SCRATCH + 4
+#define BNX2_SHM_HDR_ADDR_1				BNX2_MCP_SCRATCH + 8
+
 
 #define NUM_MC_HASH_REGISTERS   8
 
@@ -4052,6 +4061,8 @@ struct bnx2 {
 
 	u8			mac_addr[8];
 
+	u32			shmem_base;
+
 	u32			fw_ver;
 
 	int			pm_cap;
@@ -4191,6 +4202,38 @@ struct fw_info {
 #define BNX2_FW_MSG_STATUS_FAILURE		 0x00ff0000
 
 #define BNX2_LINK_STATUS			0x0000000c
+#define BNX2_LINK_STATUS_INIT_VALUE		 0xffffffff 
+#define BNX2_LINK_STATUS_LINK_UP		 0x1 
+#define BNX2_LINK_STATUS_LINK_DOWN		 0x0 
+#define BNX2_LINK_STATUS_SPEED_MASK		 0x1e
+#define BNX2_LINK_STATUS_AN_INCOMPLETE		 (0<<1) 
+#define BNX2_LINK_STATUS_10HALF			 (1<<1) 
+#define BNX2_LINK_STATUS_10FULL			 (2<<1) 
+#define BNX2_LINK_STATUS_100HALF		 (3<<1) 
+#define BNX2_LINK_STATUS_100BASE_T4		 (4<<1) 
+#define BNX2_LINK_STATUS_100FULL		 (5<<1) 
+#define BNX2_LINK_STATUS_1000HALF		 (6<<1) 
+#define BNX2_LINK_STATUS_1000FULL		 (7<<1) 
+#define BNX2_LINK_STATUS_2500HALF		 (8<<1) 
+#define BNX2_LINK_STATUS_2500FULL		 (9<<1) 
+#define BNX2_LINK_STATUS_AN_ENABLED		 (1<<5) 
+#define BNX2_LINK_STATUS_AN_COMPLETE		 (1<<6) 
+#define BNX2_LINK_STATUS_PARALLEL_DET		 (1<<7) 
+#define BNX2_LINK_STATUS_RESERVED		 (1<<8) 
+#define BNX2_LINK_STATUS_PARTNER_AD_1000FULL	 (1<<9) 
+#define BNX2_LINK_STATUS_PARTNER_AD_1000HALF	 (1<<10) 
+#define BNX2_LINK_STATUS_PARTNER_AD_100BT4	 (1<<11) 
+#define BNX2_LINK_STATUS_PARTNER_AD_100FULL	 (1<<12) 
+#define BNX2_LINK_STATUS_PARTNER_AD_100HALF	 (1<<13) 
+#define BNX2_LINK_STATUS_PARTNER_AD_10FULL	 (1<<14) 
+#define BNX2_LINK_STATUS_PARTNER_AD_10HALF	 (1<<15) 
+#define BNX2_LINK_STATUS_TX_FC_ENABLED		 (1<<16) 
+#define BNX2_LINK_STATUS_RX_FC_ENABLED		 (1<<17) 
+#define BNX2_LINK_STATUS_PARTNER_SYM_PAUSE_CAP	 (1<<18) 
+#define BNX2_LINK_STATUS_PARTNER_ASYM_PAUSE_CAP	 (1<<19) 
+#define BNX2_LINK_STATUS_SERDES_LINK		 (1<<20) 
+#define BNX2_LINK_STATUS_PARTNER_AD_2500FULL	 (1<<21) 
+#define BNX2_LINK_STATUS_PARTNER_AD_2500HALF	 (1<<22) 
 
 #define BNX2_DRV_PULSE_MB			0x00000010
 #define BNX2_DRV_PULSE_SEQ_MASK			 0x00007fff
---
0.99.8.GIT


--- NEW FILE 2463-bnx2-refine-bnx2_poll.txt ---
Subject: [PATCH] bnx2: refine bnx2_poll
From: Michael Chan <mchan at broadcom.com>
Date: 1131123228 -0800

Refine bnx2_poll() logic to write back the most up-to-date status tag
when all work has been processed. This eliminates some occasional
extra interrupts when a older status tag is written even though all
work has been processed.

The idea is to read the status tag just before exiting bnx2_poll() and
then check again for any new work. If no new work is pending, the
status tag written back will not generate any extra interrupt. This
logic is similar to the changes David Miller did to tg3_poll().

Signed-off-by: Michael Chan <mchan at broadcom.com>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/bnx2.c |   55 ++++++++++++++++++++++++++++++++++++++--------------
 drivers/net/bnx2.h |    3 +++
 2 files changed, 43 insertions(+), 15 deletions(-)

applies-to: 3de20299e878d60d7b5904f572f325f432e8891e
f4e418f7f3286f854883f9f7e3bbf7005340d2de
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index affb673..aa6d30e 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -1533,10 +1533,11 @@ bnx2_phy_int(struct bnx2 *bp)
 static void
 bnx2_tx_int(struct bnx2 *bp)
 {
+	struct status_block *sblk = bp->status_blk;
 	u16 hw_cons, sw_cons, sw_ring_cons;
 	int tx_free_bd = 0;
 
-	hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
+	hw_cons = bp->hw_tx_cons = sblk->status_tx_quick_consumer_index0;
 	if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
 		hw_cons++;
 	}
@@ -1591,7 +1592,9 @@ bnx2_tx_int(struct bnx2 *bp)
 
 		dev_kfree_skb_irq(skb);
 
-		hw_cons = bp->status_blk->status_tx_quick_consumer_index0;
+		hw_cons = bp->hw_tx_cons =
+			sblk->status_tx_quick_consumer_index0;
+
 		if ((hw_cons & MAX_TX_DESC_CNT) == MAX_TX_DESC_CNT) {
 			hw_cons++;
 		}
@@ -1636,11 +1639,12 @@ bnx2_reuse_rx_skb(struct bnx2 *bp, struc
 static int
 bnx2_rx_int(struct bnx2 *bp, int budget)
 {
+	struct status_block *sblk = bp->status_blk;
 	u16 hw_cons, sw_cons, sw_ring_cons, sw_prod, sw_ring_prod;
 	struct l2_fhdr *rx_hdr;
 	int rx_pkt = 0;
 
-	hw_cons = bp->status_blk->status_rx_quick_consumer_index0;
+	hw_cons = bp->hw_rx_cons = sblk->status_rx_quick_consumer_index0;
 	if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT) {
 		hw_cons++;
 	}
@@ -1760,6 +1764,15 @@ next_rx:
 
 		if ((rx_pkt == budget))
 			break;
+
+		/* Refresh hw_cons to see if there is new work */
+		if (sw_cons == hw_cons) {
+			hw_cons = bp->hw_rx_cons =
+				sblk->status_rx_quick_consumer_index0;
+			if ((hw_cons & MAX_RX_DESC_CNT) == MAX_RX_DESC_CNT)
+				hw_cons++;
+			rmb();
+		}
 	}
 	bp->rx_cons = sw_cons;
 	bp->rx_prod = sw_prod;
@@ -1827,15 +1840,27 @@ bnx2_interrupt(int irq, void *dev_instan
 	return IRQ_HANDLED;
 }
 
+static inline int
+bnx2_has_work(struct bnx2 *bp)
+{
+	struct status_block *sblk = bp->status_blk;
+
+	if ((sblk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) ||
+	    (sblk->status_tx_quick_consumer_index0 != bp->hw_tx_cons))
+		return 1;
+
+	if (((sblk->status_attn_bits & STATUS_ATTN_BITS_LINK_STATE) != 0) !=
+	    bp->link_up)
+		return 1;
+
+	return 0;
+}
+
 static int
 bnx2_poll(struct net_device *dev, int *budget)
 {
 	struct bnx2 *bp = dev->priv;
-	int rx_done = 1;
 
-	bp->last_status_idx = bp->status_blk->status_idx;
-
-	rmb();
 	if ((bp->status_blk->status_attn_bits &
 		STATUS_ATTN_BITS_LINK_STATE) !=
 		(bp->status_blk->status_attn_bits_ack &
@@ -1846,11 +1871,10 @@ bnx2_poll(struct net_device *dev, int *b
 		spin_unlock(&bp->phy_lock);
 	}
 
-	if (bp->status_blk->status_tx_quick_consumer_index0 != bp->tx_cons) {
+	if (bp->status_blk->status_tx_quick_consumer_index0 != bp->hw_tx_cons)
 		bnx2_tx_int(bp);
-	}
 
-	if (bp->status_blk->status_rx_quick_consumer_index0 != bp->rx_cons) {
+	if (bp->status_blk->status_rx_quick_consumer_index0 != bp->hw_rx_cons) {
 		int orig_budget = *budget;
 		int work_done;
 
@@ -1860,13 +1884,12 @@ bnx2_poll(struct net_device *dev, int *b
 		work_done = bnx2_rx_int(bp, orig_budget);
 		*budget -= work_done;
 		dev->quota -= work_done;
-		
-		if (work_done >= orig_budget) {
-			rx_done = 0;
-		}
 	}
 	
-	if (rx_done) {
+	bp->last_status_idx = bp->status_blk->status_idx;
+	rmb();
+
+	if (!bnx2_has_work(bp)) {
 		netif_rx_complete(dev);
 		REG_WR(bp, BNX2_PCICFG_INT_ACK_CMD,
 			BNX2_PCICFG_INT_ACK_CMD_INDEX_VALID |
@@ -3222,6 +3245,7 @@ bnx2_init_tx_ring(struct bnx2 *bp)
 
 	bp->tx_prod = 0;
 	bp->tx_cons = 0;
+	bp->hw_tx_cons = 0;
 	bp->tx_prod_bseq = 0;
 	
 	val = BNX2_L2CTX_TYPE_TYPE_L2;
@@ -3254,6 +3278,7 @@ bnx2_init_rx_ring(struct bnx2 *bp)
 
 	ring_prod = prod = bp->rx_prod = 0;
 	bp->rx_cons = 0;
+	bp->hw_rx_cons = 0;
 	bp->rx_prod_bseq = 0;
 		
 	rxbd = &bp->rx_desc_ring[0];
diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h
index 012586e..76bb5f1 100644
--- a/drivers/net/bnx2.h
+++ b/drivers/net/bnx2.h
@@ -3914,6 +3914,9 @@ struct bnx2 {
 	u16			tx_cons;
 	int			tx_ring_size;
 
+	u16			hw_tx_cons;
+	u16			hw_rx_cons;
+
 #ifdef BCM_VLAN 
 	struct			vlan_group *vlgrp;
 #endif
---
0.99.8.GIT


--- NEW FILE 2464-bnx2-update-version-and-minor-fixes.txt ---
Subject: [PATCH] bnx2: update version and minor fixes
From: Michael Chan <mchan at broadcom.com>
Date: 1131123228 -0800

Some book keeping and a style fix.

Signed-off-by: Michael Chan <mchan at broadcom.com>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/bnx2.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

applies-to: 655a1c3c3ea012e0521b83728034b7a675ae8e5f
05d0f1cf69fd589634b38b6f6e4b8cfdaace9ca0
diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c
index aa6d30e..8f46427 100644
--- a/drivers/net/bnx2.c
+++ b/drivers/net/bnx2.c
@@ -14,8 +14,8 @@
 
 #define DRV_MODULE_NAME		"bnx2"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"1.2.21"
-#define DRV_MODULE_RELDATE	"September 7, 2005"
+#define DRV_MODULE_VERSION	"1.4.30"
+#define DRV_MODULE_RELDATE	"October 11, 2005"
 
 #define RUN_AT(x) (jiffies + (x))
 
@@ -26,7 +26,7 @@ static char version[] __devinitdata =
 	"Broadcom NetXtreme II Gigabit Ethernet Driver " DRV_MODULE_NAME " v" DRV_MODULE_VERSION " (" DRV_MODULE_RELDATE ")\n";
 
 MODULE_AUTHOR("Michael Chan <mchan at broadcom.com>");
-MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706 Driver");
+MODULE_DESCRIPTION("Broadcom NetXtreme II BCM5706/5708 Driver");
 MODULE_LICENSE("GPL");
 MODULE_VERSION(DRV_MODULE_VERSION);
 
@@ -3364,7 +3364,7 @@ bnx2_free_rx_skbs(struct bnx2 *bp)
 		struct sw_bd *rx_buf = &bp->rx_buf_ring[i];
 		struct sk_buff *skb = rx_buf->skb;
 
-		if (skb == 0)
+		if (skb == NULL)
 			continue;
 
 		pci_unmap_single(bp->pdev, pci_unmap_addr(rx_buf, mapping),
---
0.99.8.GIT


--- NEW FILE 2468-netdrvr-fac_8xx-build-fix.txt ---
Subject: [PATCH] [netdrvr] fac_8xx build fix
From: Jeff Garzik <jgarzik at pobox.com>
Date: 1131252016 -0500

---

 drivers/net/fec_8xx/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 17d005c40d926090edfb293b5b2d44b73d2cd0c6
ecf8b596cf636c14896841625d552e148585ad07
diff --git a/drivers/net/fec_8xx/Kconfig b/drivers/net/fec_8xx/Kconfig
index 4560026..94e7a9a 100644
--- a/drivers/net/fec_8xx/Kconfig
+++ b/drivers/net/fec_8xx/Kconfig
@@ -1,6 +1,6 @@
 config FEC_8XX
 	tristate "Motorola 8xx FEC driver"
-	depends on NET_ETHERNET
+	depends on NET_ETHERNET && FEC
 	select MII
 
 config FEC_8XX_GENERIC_PHY
---
0.99.8.GIT


--- NEW FILE 2469-netdrvr-s2io-warning-fixes.txt ---
Subject: [PATCH] [netdrvr s2io] warning fixes
From: Jeff Garzik <jgarzik at pobox.com>
Date: 1131252046 -0500

>From Andrew Morton.

---

 drivers/net/s2io.c |   10 ++++------
 1 files changed, 4 insertions(+), 6 deletions(-)

applies-to: 3b978312868b35a1dd6ea5ef5d71dc8172e6f50f
50eb80068001871339d04b749fb9b198428b56d2
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 9c49354..0745dd9 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -2110,7 +2110,7 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxd
 {
 	struct net_device *dev = nic->dev;
 	struct sk_buff *frag_list;
-	u64 tmp;
+	void *tmp;
 
 	/* Buffer-1 receives L3/L4 headers */
 	((RxD3_t*)rxdp)->Buffer1_ptr = pci_map_single
@@ -2125,11 +2125,9 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxd
 	}
 	frag_list = skb_shinfo(skb)->frag_list;
 	frag_list->next = NULL;
-	tmp = (u64) frag_list->data;
-	tmp += ALIGN_SIZE;
-	tmp &= ~ALIGN_SIZE;
-	frag_list->data = (void *) tmp;
-	frag_list->tail = (void *) tmp;
+	tmp = (void *)ALIGN((long)frag_list->data, ALIGN_SIZE + 1);
+	frag_list->data = tmp;
+	frag_list->tail = tmp;
 
 	/* Buffer-2 receives L4 data payload */
 	((RxD3_t*)rxdp)->Buffer2_ptr = pci_map_single(nic->pdev,
---
0.99.8.GIT


--- NEW FILE 2576-b44-b44_start_xmit-returns-with-a-lock-held-when-it-fails-allocating.txt ---
Subject: [PATCH] b44: b44_start_xmit returns with a lock held when it fails allocating
From: Francois Romieu <romieu at fr.zoreil.com>
Date: 1131324603 +0100

The patch simply factors out the release of the lock.

Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |   17 +++++++++++------
 1 files changed, 11 insertions(+), 6 deletions(-)

applies-to: 595e0503cc152dcc5383f1f2d12e93770ae7c16b
c719369350bc566d2643067421fbf05f4b90e70b
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 0ee3e27..b334cc3 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -948,6 +948,7 @@ static int b44_start_xmit(struct sk_buff
 {
 	struct b44 *bp = netdev_priv(dev);
 	struct sk_buff *bounce_skb;
+	int rc = NETDEV_TX_OK;
 	dma_addr_t mapping;
 	u32 len, entry, ctrl;
 
@@ -957,10 +958,9 @@ static int b44_start_xmit(struct sk_buff
 	/* This is a hard error, log it. */
 	if (unlikely(TX_BUFFS_AVAIL(bp) < 1)) {
 		netif_stop_queue(dev);
-		spin_unlock_irq(&bp->lock);
 		printk(KERN_ERR PFX "%s: BUG! Tx Ring full when queue awake!\n",
 		       dev->name);
-		return 1;
+		goto err_out;
 	}
 
 	mapping = pci_map_single(bp->pdev, skb->data, len, PCI_DMA_TODEVICE);
@@ -971,7 +971,7 @@ static int b44_start_xmit(struct sk_buff
 		bounce_skb = __dev_alloc_skb(TX_PKT_BUF_SZ,
 					     GFP_ATOMIC|GFP_DMA);
 		if (!bounce_skb)
-			return NETDEV_TX_BUSY;
+			goto err_out;
 
 		mapping = pci_map_single(bp->pdev, bounce_skb->data,
 					 len, PCI_DMA_TODEVICE);
@@ -979,7 +979,7 @@ static int b44_start_xmit(struct sk_buff
 			pci_unmap_single(bp->pdev, mapping,
 					 len, PCI_DMA_TODEVICE);
 			dev_kfree_skb_any(bounce_skb);
-			return NETDEV_TX_BUSY;
+			goto err_out;
 		}
 
 		memcpy(skb_put(bounce_skb, len), skb->data, skb->len);
@@ -1019,11 +1019,16 @@ static int b44_start_xmit(struct sk_buff
 	if (TX_BUFFS_AVAIL(bp) < 1)
 		netif_stop_queue(dev);
 
+	dev->trans_start = jiffies;
+
+out_unlock:
 	spin_unlock_irq(&bp->lock);
 
-	dev->trans_start = jiffies;
+	return rc;
 
-	return 0;
+err_out:
+	rc = NETDEV_TX_BUSY;
+	goto out_unlock;
 }
 
 static int b44_change_mtu(struct net_device *dev, int new_mtu)
---
0.99.8.GIT


--- NEW FILE 2579-b44-s-spin_lock_irqsave-spin_lock-in-b44_interrupt.txt ---
Subject: [PATCH] b44: s/spin_lock_irqsave/spin_lock/ in b44_interrupt
From: Francois Romieu <romieu at fr.zoreil.com>
Date: 1131324726 +0100

There is no need to save/restore the irq state as the irq are always
locally disabled when b44_interrupt is issued.

Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |    5 ++---
 1 files changed, 2 insertions(+), 3 deletions(-)

applies-to: 6f76506a9ebe0be3a0fde5b214a01fd95000548a
65b984f26f16e97168ee29e53145055412f38a23
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index ac223fc..09e1b4d 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -895,11 +895,10 @@ static irqreturn_t b44_interrupt(int irq
 {
 	struct net_device *dev = dev_id;
 	struct b44 *bp = netdev_priv(dev);
-	unsigned long flags;
 	u32 istat, imask;
 	int handled = 0;
 
-	spin_lock_irqsave(&bp->lock, flags);
+	spin_lock(&bp->lock);
 
 	istat = br32(bp, B44_ISTAT);
 	imask = br32(bp, B44_IMASK);
@@ -925,7 +924,7 @@ static irqreturn_t b44_interrupt(int irq
 		bw32(bp, B44_ISTAT, istat);
 		br32(bp, B44_ISTAT);
 	}
-	spin_unlock_irqrestore(&bp->lock, flags);
+	spin_unlock(&bp->lock);
 	return IRQ_RETVAL(handled);
 }
 
---
0.99.8.GIT


--- NEW FILE 2580-b44-late-request_irq-in-b44_open.txt ---
Subject: [PATCH] b44: late request_irq in b44_open
From: Francois Romieu <romieu at fr.zoreil.com>
Date: 1131324777 +0100

Don't request_irq before the registers are reset/init.

Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |   22 +++++++++-------------
 1 files changed, 9 insertions(+), 13 deletions(-)

applies-to: ece6ca6ed3844220c92e4b1207542864f70bad39
6c2f4267833f453156f8f439cc32eb4c92f357b4
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index 09e1b4d..ecc2e32 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1388,13 +1388,7 @@ static int b44_open(struct net_device *d
 
 	err = b44_alloc_consistent(bp);
 	if (err)
-		return err;
-
-	err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
-	if (err)
-		goto err_out_free;
-
-	spin_lock_irq(&bp->lock);
+		goto out;
 
 	b44_init_rings(bp);
 	b44_init_hw(bp);
@@ -1403,7 +1397,13 @@ static int b44_open(struct net_device *d
 	netif_carrier_off(dev);
 	b44_check_phy(bp);
 
-	spin_unlock_irq(&bp->lock);
+	err = request_irq(dev->irq, b44_interrupt, SA_SHIRQ, dev->name, dev);
+	if (unlikely(err < 0)) {
+		b44_chip_reset(bp);
+		b44_free_rings(bp);
+		b44_free_consistent(bp);
+		goto out;
+	}
 
 	init_timer(&bp->timer);
 	bp->timer.expires = jiffies + HZ;
@@ -1412,11 +1412,7 @@ static int b44_open(struct net_device *d
 	add_timer(&bp->timer);
 
 	b44_enable_ints(bp);
-
-	return 0;
-
-err_out_free:
-	b44_free_consistent(bp);
+out:
 	return err;
 }
 
---
0.99.8.GIT


--- NEW FILE 2612-3c59x-convert-to-use-of-pci_iomap-API.txt ---
Subject: [PATCH] 3c59x: convert to use of pci_iomap API
From: John W. Linville <linville at tuxdriver.com>
Date: 1131353882 -0800

Convert 3c59x driver to use pci_iomap API.  This makes it easier to enable
the use of memory-mapped PCI I/O resources.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |  507 ++++++++++++++++++++++++++-------------------------
 1 files changed, 260 insertions(+), 247 deletions(-)

applies-to: 5df1bfd49f2e9be33505ba900d2ed153fed9a2af
62afe595de7aaac6c140103a34dc8c208afa34e7
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 455ba91..2bad41b 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -602,7 +602,7 @@ MODULE_DEVICE_TABLE(pci, vortex_pci_tbl)
    First the windows.  There are eight register windows, with the command
    and status registers available in each.
    */
-#define EL3WINDOW(win_num) outw(SelectWindow + (win_num), ioaddr + EL3_CMD)
+#define EL3WINDOW(win_num) iowrite16(SelectWindow + (win_num), ioaddr + EL3_CMD)
 #define EL3_CMD 0x0e
 #define EL3_STATUS 0x0e
 
@@ -776,7 +776,8 @@ struct vortex_private {
 
 	/* PCI configuration space information. */
 	struct device *gendev;
-	char __iomem *cb_fn_base;		/* CardBus function status addr space. */
+	void __iomem *ioaddr;			/* IO address space */
+	void __iomem *cb_fn_base;		/* CardBus function status addr space. */
 
 	/* Some values here only for performance evaluation and path-coverage */
 	int rx_nocopy, rx_copy, queued_packet, rx_csumhits;
@@ -869,12 +870,12 @@ static struct {
 /* number of ETHTOOL_GSTATS u64's */
 #define VORTEX_NUM_STATS     3
 
-static int vortex_probe1(struct device *gendev, long ioaddr, int irq,
+static int vortex_probe1(struct device *gendev, void __iomem *ioaddr, int irq,
 				   int chip_idx, int card_idx);
 static void vortex_up(struct net_device *dev);
 static void vortex_down(struct net_device *dev, int final);
 static int vortex_open(struct net_device *dev);
-static void mdio_sync(long ioaddr, int bits);
+static void mdio_sync(void __iomem *ioaddr, int bits);
 static int mdio_read(struct net_device *dev, int phy_id, int location);
 static void mdio_write(struct net_device *vp, int phy_id, int location, int value);
 static void vortex_timer(unsigned long arg);
@@ -887,7 +888,7 @@ static irqreturn_t vortex_interrupt(int 
 static irqreturn_t boomerang_interrupt(int irq, void *dev_id, struct pt_regs *regs);
 static int vortex_close(struct net_device *dev);
 static void dump_tx_ring(struct net_device *dev);
-static void update_stats(long ioaddr, struct net_device *dev);
+static void update_stats(void __iomem *ioaddr, struct net_device *dev);
 static struct net_device_stats *vortex_get_stats(struct net_device *dev);
 static void set_rx_mode(struct net_device *dev);
 #ifdef CONFIG_PCI
@@ -1029,18 +1030,19 @@ static struct eisa_driver vortex_eisa_dr
 
 static int vortex_eisa_probe (struct device *device)
 {
-	long ioaddr;
+	void __iomem *ioaddr;
 	struct eisa_device *edev;
 
 	edev = to_eisa_device (device);
-	ioaddr = edev->base_addr;
 
-	if (!request_region(ioaddr, VORTEX_TOTAL_SIZE, DRV_NAME))
+	if (!request_region(edev->base_addr, VORTEX_TOTAL_SIZE, DRV_NAME))
 		return -EBUSY;
 
-	if (vortex_probe1(device, ioaddr, inw(ioaddr + 0xC88) >> 12,
+	ioaddr = ioport_map(edev->base_addr, VORTEX_TOTAL_SIZE);
+
+	if (vortex_probe1(device, ioaddr, ioread16(ioaddr + 0xC88) >> 12,
 					  edev->id.driver_data, vortex_cards_found)) {
-		release_region (ioaddr, VORTEX_TOTAL_SIZE);
+		release_region (edev->base_addr, VORTEX_TOTAL_SIZE);
 		return -ENODEV;
 	}
 
@@ -1054,7 +1056,7 @@ static int vortex_eisa_remove (struct de
 	struct eisa_device *edev;
 	struct net_device *dev;
 	struct vortex_private *vp;
-	long ioaddr;
+	void __iomem *ioaddr;
 
 	edev = to_eisa_device (device);
 	dev = eisa_get_drvdata (edev);
@@ -1065,11 +1067,11 @@ static int vortex_eisa_remove (struct de
 	}
 
 	vp = netdev_priv(dev);
-	ioaddr = dev->base_addr;
+	ioaddr = vp->ioaddr;
 	
 	unregister_netdev (dev);
-	outw (TotalReset|0x14, ioaddr + EL3_CMD);
-	release_region (ioaddr, VORTEX_TOTAL_SIZE);
+	iowrite16 (TotalReset|0x14, ioaddr + EL3_CMD);
+	release_region (dev->base_addr, VORTEX_TOTAL_SIZE);
 
 	free_netdev (dev);
 	return 0;
@@ -1096,8 +1098,8 @@ static int __init vortex_eisa_init (void
 	
 	/* Special code to work-around the Compaq PCI BIOS32 problem. */
 	if (compaq_ioaddr) {
-		vortex_probe1(NULL, compaq_ioaddr, compaq_irq,
-					  compaq_device_id, vortex_cards_found++);
+		vortex_probe1(NULL, ioport_map(compaq_ioaddr, VORTEX_TOTAL_SIZE),
+			      compaq_irq, compaq_device_id, vortex_cards_found++);
 	}
 
 	return vortex_cards_found - orig_cards_found + eisa_found;
@@ -1114,8 +1116,8 @@ static int __devinit vortex_init_one (st
 	if (rc < 0)
 		goto out;
 
-	rc = vortex_probe1 (&pdev->dev, pci_resource_start (pdev, 0),
-						pdev->irq, ent->driver_data, vortex_cards_found);
+	rc = vortex_probe1 (&pdev->dev, pci_iomap(pdev, 0, 0),
+			    pdev->irq, ent->driver_data, vortex_cards_found);
 	if (rc < 0) {
 		pci_disable_device (pdev);
 		goto out;
@@ -1134,7 +1136,7 @@ out:
  * NOTE: pdev can be NULL, for the case of a Compaq device
  */
 static int __devinit vortex_probe1(struct device *gendev,
-				   long ioaddr, int irq,
+				   void __iomem *ioaddr, int irq,
 				   int chip_idx, int card_idx)
 {
 	struct vortex_private *vp;
@@ -1202,15 +1204,16 @@ static int __devinit vortex_probe1(struc
 	if (print_info)
 		printk (KERN_INFO "See Documentation/networking/vortex.txt\n");
 
-	printk(KERN_INFO "%s: 3Com %s %s at 0x%lx. Vers " DRV_VERSION "\n",
+	printk(KERN_INFO "%s: 3Com %s %s at %p. Vers " DRV_VERSION "\n",
 	       print_name,
 	       pdev ? "PCI" : "EISA",
 	       vci->name,
 	       ioaddr);
 
-	dev->base_addr = ioaddr;
+	dev->base_addr = (unsigned long)ioaddr;
 	dev->irq = irq;
 	dev->mtu = mtu;
+	vp->ioaddr = ioaddr;
 	vp->large_frames = mtu > 1500;
 	vp->drv_flags = vci->drv_flags;
 	vp->has_nway = (vci->drv_flags & HAS_NWAY) ? 1 : 0;
@@ -1226,7 +1229,7 @@ static int __devinit vortex_probe1(struc
 	if (pdev) {
 		/* EISA resources already marked, so only PCI needs to do this here */
 		/* Ignore return value, because Cardbus drivers already allocate for us */
-		if (request_region(ioaddr, vci->io_size, print_name) != NULL)
+		if (request_region(dev->base_addr, vci->io_size, print_name) != NULL)
 			vp->must_free_region = 1;
 
 		/* enable bus-mastering if necessary */		
@@ -1316,14 +1319,14 @@ static int __devinit vortex_probe1(struc
 
 		for (i = 0; i < 0x40; i++) {
 			int timer;
-			outw(base + i, ioaddr + Wn0EepromCmd);
+			iowrite16(base + i, ioaddr + Wn0EepromCmd);
 			/* Pause for at least 162 us. for the read to take place. */
 			for (timer = 10; timer >= 0; timer--) {
 				udelay(162);
-				if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
+				if ((ioread16(ioaddr + Wn0EepromCmd) & 0x8000) == 0)
 					break;
 			}
-			eeprom[i] = inw(ioaddr + Wn0EepromData);
+			eeprom[i] = ioread16(ioaddr + Wn0EepromData);
 		}
 	}
 	for (i = 0; i < 0x18; i++)
@@ -1351,7 +1354,7 @@ static int __devinit vortex_probe1(struc
 	}
 	EL3WINDOW(2);
 	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + i);
+		iowrite8(dev->dev_addr[i], ioaddr + i);
 
 #ifdef __sparc__
 	if (print_info)
@@ -1366,7 +1369,7 @@ static int __devinit vortex_probe1(struc
 #endif
 
 	EL3WINDOW(4);
-	step = (inb(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
+	step = (ioread8(ioaddr + Wn4_NetDiag) & 0x1e) >> 1;
 	if (print_info) {
 		printk(KERN_INFO "  product code %02x%02x rev %02x.%d date %02d-"
 			"%02d-%02d\n", eeprom[6]&0xff, eeprom[6]>>8, eeprom[0x14],
@@ -1375,31 +1378,30 @@ static int __devinit vortex_probe1(struc
 
 
 	if (pdev && vci->drv_flags & HAS_CB_FNS) {
-		unsigned long fn_st_addr;			/* Cardbus function status space */
 		unsigned short n;
 
-		fn_st_addr = pci_resource_start (pdev, 2);
-		if (fn_st_addr) {
-			vp->cb_fn_base = ioremap(fn_st_addr, 128);
+		vp->cb_fn_base = pci_iomap(pdev, 2, 0);
+		if (!vp->cb_fn_base) {
 			retval = -ENOMEM;
-			if (!vp->cb_fn_base)
-				goto free_ring;
+			goto free_ring;
 		}
+
 		if (print_info) {
 			printk(KERN_INFO "%s: CardBus functions mapped %8.8lx->%p\n",
-				print_name, fn_st_addr, vp->cb_fn_base);
+				print_name, pci_resource_start(pdev, 2),
+				vp->cb_fn_base);
 		}
 		EL3WINDOW(2);
 
-		n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
+		n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
 		if (vp->drv_flags & INVERT_LED_PWR)
 			n |= 0x10;
 		if (vp->drv_flags & INVERT_MII_PWR)
 			n |= 0x4000;
-		outw(n, ioaddr + Wn2_ResetOptions);
+		iowrite16(n, ioaddr + Wn2_ResetOptions);
 		if (vp->drv_flags & WNO_XCVR_PWR) {
 			EL3WINDOW(0);
-			outw(0x0800, ioaddr);
+			iowrite16(0x0800, ioaddr);
 		}
 	}
 
@@ -1418,13 +1420,13 @@ static int __devinit vortex_probe1(struc
 		static const char * ram_split[] = {"5:3", "3:1", "1:1", "3:5"};
 		unsigned int config;
 		EL3WINDOW(3);
-		vp->available_media = inw(ioaddr + Wn3_Options);
+		vp->available_media = ioread16(ioaddr + Wn3_Options);
 		if ((vp->available_media & 0xff) == 0)		/* Broken 3c916 */
 			vp->available_media = 0x40;
-		config = inl(ioaddr + Wn3_Config);
+		config = ioread32(ioaddr + Wn3_Config);
 		if (print_info) {
 			printk(KERN_DEBUG "  Internal config register is %4.4x, "
-				   "transceivers %#x.\n", config, inw(ioaddr + Wn3_Options));
+				   "transceivers %#x.\n", config, ioread16(ioaddr + Wn3_Options));
 			printk(KERN_INFO "  %dK %s-wide RAM %s Rx:Tx split, %s%s interface.\n",
 				   8 << RAM_SIZE(config),
 				   RAM_WIDTH(config) ? "word" : "byte",
@@ -1555,7 +1557,7 @@ free_ring:
 						vp->rx_ring_dma);
 free_region:
 	if (vp->must_free_region)
-		release_region(ioaddr, vci->io_size);
+		release_region(dev->base_addr, vci->io_size);
 	free_netdev(dev);
 	printk(KERN_ERR PFX "vortex_probe1 fails.  Returns %d\n", retval);
 out:
@@ -1565,17 +1567,19 @@ out:
 static void
 issue_and_wait(struct net_device *dev, int cmd)
 {
+	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	int i;
 
-	outw(cmd, dev->base_addr + EL3_CMD);
+	iowrite16(cmd, ioaddr + EL3_CMD);
 	for (i = 0; i < 2000; i++) {
-		if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress))
+		if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
 			return;
 	}
 
 	/* OK, that didn't work.  Do it the slow way.  One second */
 	for (i = 0; i < 100000; i++) {
-		if (!(inw(dev->base_addr + EL3_STATUS) & CmdInProgress)) {
+		if (!(ioread16(ioaddr + EL3_STATUS) & CmdInProgress)) {
 			if (vortex_debug > 1)
 				printk(KERN_INFO "%s: command 0x%04x took %d usecs\n",
 					   dev->name, cmd, i * 10);
@@ -1584,14 +1588,14 @@ issue_and_wait(struct net_device *dev, i
 		udelay(10);
 	}
 	printk(KERN_ERR "%s: command 0x%04x did not complete! Status=0x%x\n",
-			   dev->name, cmd, inw(dev->base_addr + EL3_STATUS));
+			   dev->name, cmd, ioread16(ioaddr + EL3_STATUS));
 }
 
 static void
 vortex_up(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
 	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned int config;
 	int i;
 
@@ -1604,7 +1608,7 @@ vortex_up(struct net_device *dev)
 
 	/* Before initializing select the active media port. */
 	EL3WINDOW(3);
-	config = inl(ioaddr + Wn3_Config);
+	config = ioread32(ioaddr + Wn3_Config);
 
 	if (vp->media_override != 7) {
 		printk(KERN_INFO "%s: Media override to transceiver %d (%s).\n",
@@ -1651,7 +1655,7 @@ vortex_up(struct net_device *dev)
 	config = BFINS(config, dev->if_port, 20, 4);
 	if (vortex_debug > 6)
 		printk(KERN_DEBUG "vortex_up(): writing 0x%x to InternalConfig\n", config);
-	outl(config, ioaddr + Wn3_Config);
+	iowrite32(config, ioaddr + Wn3_Config);
 
 	if (dev->if_port == XCVR_MII || dev->if_port == XCVR_NWAY) {
 		int mii_reg1, mii_reg5;
@@ -1679,7 +1683,7 @@ vortex_up(struct net_device *dev)
 	}
 
 	/* Set the full-duplex bit. */
-	outw(	((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
+	iowrite16(	((vp->info1 & 0x8000) || vp->full_duplex ? 0x20 : 0) |
 		 	(vp->large_frames ? 0x40 : 0) |
 			((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
 			ioaddr + Wn3_MAC_Ctrl);
@@ -1695,51 +1699,51 @@ vortex_up(struct net_device *dev)
 	 */
 	issue_and_wait(dev, RxReset|0x04);
 
-	outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
+	iowrite16(SetStatusEnb | 0x00, ioaddr + EL3_CMD);
 
 	if (vortex_debug > 1) {
 		EL3WINDOW(4);
 		printk(KERN_DEBUG "%s: vortex_up() irq %d media status %4.4x.\n",
-			   dev->name, dev->irq, inw(ioaddr + Wn4_Media));
+			   dev->name, dev->irq, ioread16(ioaddr + Wn4_Media));
 	}
 
 	/* Set the station address and mask in window 2 each time opened. */
 	EL3WINDOW(2);
 	for (i = 0; i < 6; i++)
-		outb(dev->dev_addr[i], ioaddr + i);
+		iowrite8(dev->dev_addr[i], ioaddr + i);
 	for (; i < 12; i+=2)
-		outw(0, ioaddr + i);
+		iowrite16(0, ioaddr + i);
 
 	if (vp->cb_fn_base) {
-		unsigned short n = inw(ioaddr + Wn2_ResetOptions) & ~0x4010;
+		unsigned short n = ioread16(ioaddr + Wn2_ResetOptions) & ~0x4010;
 		if (vp->drv_flags & INVERT_LED_PWR)
 			n |= 0x10;
 		if (vp->drv_flags & INVERT_MII_PWR)
 			n |= 0x4000;
-		outw(n, ioaddr + Wn2_ResetOptions);
+		iowrite16(n, ioaddr + Wn2_ResetOptions);
 	}
 
 	if (dev->if_port == XCVR_10base2)
 		/* Start the thinnet transceiver. We should really wait 50ms...*/
-		outw(StartCoax, ioaddr + EL3_CMD);
+		iowrite16(StartCoax, ioaddr + EL3_CMD);
 	if (dev->if_port != XCVR_NWAY) {
 		EL3WINDOW(4);
-		outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
+		iowrite16((ioread16(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) |
 			 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
 	}
 
 	/* Switch to the stats window, and clear all stats by reading. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
+	iowrite16(StatsDisable, ioaddr + EL3_CMD);
 	EL3WINDOW(6);
 	for (i = 0; i < 10; i++)
-		inb(ioaddr + i);
-	inw(ioaddr + 10);
-	inw(ioaddr + 12);
+		ioread8(ioaddr + i);
+	ioread16(ioaddr + 10);
+	ioread16(ioaddr + 12);
 	/* New: On the Vortex we must also clear the BadSSD counter. */
 	EL3WINDOW(4);
-	inb(ioaddr + 12);
+	ioread8(ioaddr + 12);
 	/* ..and on the Boomerang we enable the extra statistics bits. */
-	outw(0x0040, ioaddr + Wn4_NetDiag);
+	iowrite16(0x0040, ioaddr + Wn4_NetDiag);
 
 	/* Switch to register set 7 for normal use. */
 	EL3WINDOW(7);
@@ -1747,30 +1751,30 @@ vortex_up(struct net_device *dev)
 	if (vp->full_bus_master_rx) { /* Boomerang bus master. */
 		vp->cur_rx = vp->dirty_rx = 0;
 		/* Initialize the RxEarly register as recommended. */
-		outw(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
-		outl(0x0020, ioaddr + PktStatus);
-		outl(vp->rx_ring_dma, ioaddr + UpListPtr);
+		iowrite16(SetRxThreshold + (1536>>2), ioaddr + EL3_CMD);
+		iowrite32(0x0020, ioaddr + PktStatus);
+		iowrite32(vp->rx_ring_dma, ioaddr + UpListPtr);
 	}
 	if (vp->full_bus_master_tx) { 		/* Boomerang bus master Tx. */
 		vp->cur_tx = vp->dirty_tx = 0;
 		if (vp->drv_flags & IS_BOOMERANG)
-			outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
+			iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold); /* Room for a packet. */
 		/* Clear the Rx, Tx rings. */
 		for (i = 0; i < RX_RING_SIZE; i++)	/* AKPM: this is done in vortex_open, too */
 			vp->rx_ring[i].status = 0;
 		for (i = 0; i < TX_RING_SIZE; i++)
 			vp->tx_skbuff[i] = NULL;
-		outl(0, ioaddr + DownListPtr);
+		iowrite32(0, ioaddr + DownListPtr);
 	}
 	/* Set receiver mode: presumably accept b-case and phys addr only. */
 	set_rx_mode(dev);
 	/* enable 802.1q tagged frames */
 	set_8021q_mode(dev, 1);
-	outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
+	iowrite16(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */
 
 //	issue_and_wait(dev, SetTxStart|0x07ff);
-	outw(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
-	outw(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
+	iowrite16(RxEnable, ioaddr + EL3_CMD); /* Enable the receiver. */
+	iowrite16(TxEnable, ioaddr + EL3_CMD); /* Enable transmitter. */
 	/* Allow status bits to be seen. */
 	vp->status_enable = SetStatusEnb | HostError|IntReq|StatsFull|TxComplete|
 		(vp->full_bus_master_tx ? DownComplete : TxAvailable) |
@@ -1780,13 +1784,13 @@ vortex_up(struct net_device *dev)
 		(vp->full_bus_master_rx ? 0 : RxComplete) |
 		StatsFull | HostError | TxComplete | IntReq
 		| (vp->bus_master ? DMADone : 0) | UpComplete | DownComplete;
-	outw(vp->status_enable, ioaddr + EL3_CMD);
+	iowrite16(vp->status_enable, ioaddr + EL3_CMD);
 	/* Ack all pending events, and set active indicator mask. */
-	outw(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
+	iowrite16(AckIntr | IntLatch | TxAvailable | RxEarly | IntReq,
 		 ioaddr + EL3_CMD);
-	outw(vp->intr_enable, ioaddr + EL3_CMD);
+	iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
 	if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
-		writel(0x8000, vp->cb_fn_base + 4);
+		iowrite32(0x8000, vp->cb_fn_base + 4);
 	netif_start_queue (dev);
 }
 
@@ -1852,7 +1856,7 @@ vortex_timer(unsigned long data)
 {
 	struct net_device *dev = (struct net_device *)data;
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int next_tick = 60*HZ;
 	int ok = 0;
 	int media_status, mii_status, old_window;
@@ -1866,9 +1870,9 @@ vortex_timer(unsigned long data)
 	if (vp->medialock)
 		goto leave_media_alone;
 	disable_irq(dev->irq);
-	old_window = inw(ioaddr + EL3_CMD) >> 13;
+	old_window = ioread16(ioaddr + EL3_CMD) >> 13;
 	EL3WINDOW(4);
-	media_status = inw(ioaddr + Wn4_Media);
+	media_status = ioread16(ioaddr + Wn4_Media);
 	switch (dev->if_port) {
 	case XCVR_10baseT:  case XCVR_100baseTx:  case XCVR_100baseFx:
 		if (media_status & Media_LnkBeat) {
@@ -1909,7 +1913,7 @@ vortex_timer(unsigned long data)
 							vp->phys[0], mii_reg5);
 						/* Set the full-duplex bit. */
 						EL3WINDOW(3);
-						outw(	(vp->full_duplex ? 0x20 : 0) |
+						iowrite16(	(vp->full_duplex ? 0x20 : 0) |
 								(vp->large_frames ? 0x40 : 0) |
 								((vp->full_duplex && vp->flow_ctrl && vp->partner_flow_ctrl) ? 0x100 : 0),
 								ioaddr + Wn3_MAC_Ctrl);
@@ -1950,15 +1954,15 @@ vortex_timer(unsigned long data)
 					   dev->name, media_tbl[dev->if_port].name);
 			next_tick = media_tbl[dev->if_port].wait;
 		}
-		outw((media_status & ~(Media_10TP|Media_SQE)) |
+		iowrite16((media_status & ~(Media_10TP|Media_SQE)) |
 			 media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media);
 
 		EL3WINDOW(3);
-		config = inl(ioaddr + Wn3_Config);
+		config = ioread32(ioaddr + Wn3_Config);
 		config = BFINS(config, dev->if_port, 20, 4);
-		outl(config, ioaddr + Wn3_Config);
+		iowrite32(config, ioaddr + Wn3_Config);
 
-		outw(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
+		iowrite16(dev->if_port == XCVR_10base2 ? StartCoax : StopCoax,
 			 ioaddr + EL3_CMD);
 		if (vortex_debug > 1)
 			printk(KERN_DEBUG "wrote 0x%08x to Wn3_Config\n", config);
@@ -1974,29 +1978,29 @@ leave_media_alone:
 
 	mod_timer(&vp->timer, RUN_AT(next_tick));
 	if (vp->deferred)
-		outw(FakeIntr, ioaddr + EL3_CMD);
+		iowrite16(FakeIntr, ioaddr + EL3_CMD);
 	return;
 }
 
 static void vortex_tx_timeout(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 
 	printk(KERN_ERR "%s: transmit timed out, tx_status %2.2x status %4.4x.\n",
-		   dev->name, inb(ioaddr + TxStatus),
-		   inw(ioaddr + EL3_STATUS));
+		   dev->name, ioread8(ioaddr + TxStatus),
+		   ioread16(ioaddr + EL3_STATUS));
 	EL3WINDOW(4);
 	printk(KERN_ERR "  diagnostics: net %04x media %04x dma %08x fifo %04x\n",
-			inw(ioaddr + Wn4_NetDiag),
-			inw(ioaddr + Wn4_Media),
-			inl(ioaddr + PktStatus),
-			inw(ioaddr + Wn4_FIFODiag));
+			ioread16(ioaddr + Wn4_NetDiag),
+			ioread16(ioaddr + Wn4_Media),
+			ioread32(ioaddr + PktStatus),
+			ioread16(ioaddr + Wn4_FIFODiag));
 	/* Slight code bloat to be user friendly. */
-	if ((inb(ioaddr + TxStatus) & 0x88) == 0x88)
+	if ((ioread8(ioaddr + TxStatus) & 0x88) == 0x88)
 		printk(KERN_ERR "%s: Transmitter encountered 16 collisions --"
 			   " network cable problem?\n", dev->name);
-	if (inw(ioaddr + EL3_STATUS) & IntLatch) {
+	if (ioread16(ioaddr + EL3_STATUS) & IntLatch) {
 		printk(KERN_ERR "%s: Interrupt posted but not delivered --"
 			   " IRQ blocked by another device?\n", dev->name);
 		/* Bad idea here.. but we might as well handle a few events. */
@@ -2022,21 +2026,21 @@ static void vortex_tx_timeout(struct net
 	vp->stats.tx_errors++;
 	if (vp->full_bus_master_tx) {
 		printk(KERN_DEBUG "%s: Resetting the Tx ring pointer.\n", dev->name);
-		if (vp->cur_tx - vp->dirty_tx > 0  &&  inl(ioaddr + DownListPtr) == 0)
-			outl(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
+		if (vp->cur_tx - vp->dirty_tx > 0  &&  ioread32(ioaddr + DownListPtr) == 0)
+			iowrite32(vp->tx_ring_dma + (vp->dirty_tx % TX_RING_SIZE) * sizeof(struct boom_tx_desc),
 				 ioaddr + DownListPtr);
 		if (vp->cur_tx - vp->dirty_tx < TX_RING_SIZE)
 			netif_wake_queue (dev);
 		if (vp->drv_flags & IS_BOOMERANG)
-			outb(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
-		outw(DownUnstall, ioaddr + EL3_CMD);
+			iowrite8(PKT_BUF_SZ>>8, ioaddr + TxFreeThreshold);
+		iowrite16(DownUnstall, ioaddr + EL3_CMD);
 	} else {
 		vp->stats.tx_dropped++;
 		netif_wake_queue(dev);
 	}
 	
 	/* Issue Tx Enable */
-	outw(TxEnable, ioaddr + EL3_CMD);
+	iowrite16(TxEnable, ioaddr + EL3_CMD);
 	dev->trans_start = jiffies;
 	
 	/* Switch to register set 7 for normal use. */
@@ -2051,7 +2055,7 @@ static void
 vortex_error(struct net_device *dev, int status)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int do_tx_reset = 0, reset_mask = 0;
 	unsigned char tx_status = 0;
 
@@ -2060,7 +2064,7 @@ vortex_error(struct net_device *dev, int
 	}
 
 	if (status & TxComplete) {			/* Really "TxError" for us. */
-		tx_status = inb(ioaddr + TxStatus);
+		tx_status = ioread8(ioaddr + TxStatus);
 		/* Presumably a tx-timeout. We must merely re-enable. */
 		if (vortex_debug > 2
 			|| (tx_status != 0x88 && vortex_debug > 0)) {
@@ -2074,20 +2078,20 @@ vortex_error(struct net_device *dev, int
 		}
 		if (tx_status & 0x14)  vp->stats.tx_fifo_errors++;
 		if (tx_status & 0x38)  vp->stats.tx_aborted_errors++;
-		outb(0, ioaddr + TxStatus);
+		iowrite8(0, ioaddr + TxStatus);
 		if (tx_status & 0x30) {			/* txJabber or txUnderrun */
 			do_tx_reset = 1;
 		} else if ((tx_status & 0x08) && (vp->drv_flags & MAX_COLLISION_RESET)) {	/* maxCollisions */
 			do_tx_reset = 1;
 			reset_mask = 0x0108;		/* Reset interface logic, but not download logic */
 		} else {						/* Merely re-enable the transmitter. */
-			outw(TxEnable, ioaddr + EL3_CMD);
+			iowrite16(TxEnable, ioaddr + EL3_CMD);
 		}
 	}
 
 	if (status & RxEarly) {				/* Rx early is unused. */
 		vortex_rx(dev);
-		outw(AckIntr | RxEarly, ioaddr + EL3_CMD);
+		iowrite16(AckIntr | RxEarly, ioaddr + EL3_CMD);
 	}
 	if (status & StatsFull) {			/* Empty statistics. */
 		static int DoneDidThat;
@@ -2097,29 +2101,29 @@ vortex_error(struct net_device *dev, int
 		/* HACK: Disable statistics as an interrupt source. */
 		/* This occurs when we have the wrong media type! */
 		if (DoneDidThat == 0  &&
-			inw(ioaddr + EL3_STATUS) & StatsFull) {
+			ioread16(ioaddr + EL3_STATUS) & StatsFull) {
 			printk(KERN_WARNING "%s: Updating statistics failed, disabling "
 				   "stats as an interrupt source.\n", dev->name);
 			EL3WINDOW(5);
-			outw(SetIntrEnb | (inw(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
+			iowrite16(SetIntrEnb | (ioread16(ioaddr + 10) & ~StatsFull), ioaddr + EL3_CMD);
 			vp->intr_enable &= ~StatsFull;
 			EL3WINDOW(7);
 			DoneDidThat++;
 		}
 	}
 	if (status & IntReq) {		/* Restore all interrupt sources.  */
-		outw(vp->status_enable, ioaddr + EL3_CMD);
-		outw(vp->intr_enable, ioaddr + EL3_CMD);
+		iowrite16(vp->status_enable, ioaddr + EL3_CMD);
+		iowrite16(vp->intr_enable, ioaddr + EL3_CMD);
 	}
 	if (status & HostError) {
 		u16 fifo_diag;
 		EL3WINDOW(4);
-		fifo_diag = inw(ioaddr + Wn4_FIFODiag);
+		fifo_diag = ioread16(ioaddr + Wn4_FIFODiag);
 		printk(KERN_ERR "%s: Host error, FIFO diagnostic register %4.4x.\n",
 			   dev->name, fifo_diag);
 		/* Adapter failure requires Tx/Rx reset and reinit. */
 		if (vp->full_bus_master_tx) {
-			int bus_status = inl(ioaddr + PktStatus);
+			int bus_status = ioread32(ioaddr + PktStatus);
 			/* 0x80000000 PCI master abort. */
 			/* 0x40000000 PCI target abort. */
 			if (vortex_debug)
@@ -2139,14 +2143,14 @@ vortex_error(struct net_device *dev, int
 			set_rx_mode(dev);
 			/* enable 802.1q VLAN tagged frames */
 			set_8021q_mode(dev, 1);
-			outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
-			outw(AckIntr | HostError, ioaddr + EL3_CMD);
+			iowrite16(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */
+			iowrite16(AckIntr | HostError, ioaddr + EL3_CMD);
 		}
 	}
 
 	if (do_tx_reset) {
 		issue_and_wait(dev, TxReset|reset_mask);
-		outw(TxEnable, ioaddr + EL3_CMD);
+		iowrite16(TxEnable, ioaddr + EL3_CMD);
 		if (!vp->full_bus_master_tx)
 			netif_wake_queue(dev);
 	}
@@ -2156,29 +2160,29 @@ static int
 vortex_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 
 	/* Put out the doubleword header... */
-	outl(skb->len, ioaddr + TX_FIFO);
+	iowrite32(skb->len, ioaddr + TX_FIFO);
 	if (vp->bus_master) {
 		/* Set the bus-master controller to transfer the packet. */
 		int len = (skb->len + 3) & ~3;
-		outl(	vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
+		iowrite32(	vp->tx_skb_dma = pci_map_single(VORTEX_PCI(vp), skb->data, len, PCI_DMA_TODEVICE),
 				ioaddr + Wn7_MasterAddr);
-		outw(len, ioaddr + Wn7_MasterLen);
+		iowrite16(len, ioaddr + Wn7_MasterLen);
 		vp->tx_skb = skb;
-		outw(StartDMADown, ioaddr + EL3_CMD);
+		iowrite16(StartDMADown, ioaddr + EL3_CMD);
 		/* netif_wake_queue() will be called at the DMADone interrupt. */
 	} else {
 		/* ... and the packet rounded to a doubleword. */
-		outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
+		iowrite32_rep(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2);
 		dev_kfree_skb (skb);
-		if (inw(ioaddr + TxFree) > 1536) {
+		if (ioread16(ioaddr + TxFree) > 1536) {
 			netif_start_queue (dev);	/* AKPM: redundant? */
 		} else {
 			/* Interrupt us when the FIFO has room for max-sized packet. */
 			netif_stop_queue(dev);
-			outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+			iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
 		}
 	}
 
@@ -2189,7 +2193,7 @@ vortex_start_xmit(struct sk_buff *skb, s
 		int tx_status;
 		int i = 32;
 
-		while (--i > 0	&&	(tx_status = inb(ioaddr + TxStatus)) > 0) {
+		while (--i > 0	&&	(tx_status = ioread8(ioaddr + TxStatus)) > 0) {
 			if (tx_status & 0x3C) {		/* A Tx-disabling error occurred.  */
 				if (vortex_debug > 2)
 				  printk(KERN_DEBUG "%s: Tx error, status %2.2x.\n",
@@ -2199,9 +2203,9 @@ vortex_start_xmit(struct sk_buff *skb, s
 				if (tx_status & 0x30) {
 					issue_and_wait(dev, TxReset);
 				}
-				outw(TxEnable, ioaddr + EL3_CMD);
+				iowrite16(TxEnable, ioaddr + EL3_CMD);
 			}
-			outb(0x00, ioaddr + TxStatus); /* Pop the status stack. */
+			iowrite8(0x00, ioaddr + TxStatus); /* Pop the status stack. */
 		}
 	}
 	return 0;
@@ -2211,7 +2215,7 @@ static int
 boomerang_start_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	/* Calculate the next Tx descriptor entry. */
 	int entry = vp->cur_tx % TX_RING_SIZE;
 	struct boom_tx_desc *prev_entry = &vp->tx_ring[(vp->cur_tx-1) % TX_RING_SIZE];
@@ -2275,8 +2279,8 @@ boomerang_start_xmit(struct sk_buff *skb
 	/* Wait for the stall to complete. */
 	issue_and_wait(dev, DownStall);
 	prev_entry->next = cpu_to_le32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc));
-	if (inl(ioaddr + DownListPtr) == 0) {
-		outl(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
+	if (ioread32(ioaddr + DownListPtr) == 0) {
+		iowrite32(vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc), ioaddr + DownListPtr);
 		vp->queued_packet++;
 	}
 
@@ -2291,7 +2295,7 @@ boomerang_start_xmit(struct sk_buff *skb
 		prev_entry->status &= cpu_to_le32(~TxIntrUploaded);
 #endif
 	}
-	outw(DownUnstall, ioaddr + EL3_CMD);
+	iowrite16(DownUnstall, ioaddr + EL3_CMD);
 	spin_unlock_irqrestore(&vp->lock, flags);
 	dev->trans_start = jiffies;
 	return 0;
@@ -2310,15 +2314,15 @@ vortex_interrupt(int irq, void *dev_id, 
 {
 	struct net_device *dev = dev_id;
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr;
+	void __iomem *ioaddr;
 	int status;
 	int work_done = max_interrupt_work;
 	int handled = 0;
 
-	ioaddr = dev->base_addr;
+	ioaddr = vp->ioaddr;
 	spin_lock(&vp->lock);
 
-	status = inw(ioaddr + EL3_STATUS);
+	status = ioread16(ioaddr + EL3_STATUS);
 
 	if (vortex_debug > 6)
 		printk("vortex_interrupt(). status=0x%4x\n", status);
@@ -2337,7 +2341,7 @@ vortex_interrupt(int irq, void *dev_id, 
 
 	if (vortex_debug > 4)
 		printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
-			   dev->name, status, inb(ioaddr + Timer));
+			   dev->name, status, ioread8(ioaddr + Timer));
 
 	do {
 		if (vortex_debug > 5)
@@ -2350,16 +2354,16 @@ vortex_interrupt(int irq, void *dev_id, 
 			if (vortex_debug > 5)
 				printk(KERN_DEBUG "	TX room bit was handled.\n");
 			/* There's room in the FIFO for a full-sized packet. */
-			outw(AckIntr | TxAvailable, ioaddr + EL3_CMD);
+			iowrite16(AckIntr | TxAvailable, ioaddr + EL3_CMD);
 			netif_wake_queue (dev);
 		}
 
 		if (status & DMADone) {
-			if (inw(ioaddr + Wn7_MasterStatus) & 0x1000) {
-				outw(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
+			if (ioread16(ioaddr + Wn7_MasterStatus) & 0x1000) {
+				iowrite16(0x1000, ioaddr + Wn7_MasterStatus); /* Ack the event. */
 				pci_unmap_single(VORTEX_PCI(vp), vp->tx_skb_dma, (vp->tx_skb->len + 3) & ~3, PCI_DMA_TODEVICE);
 				dev_kfree_skb_irq(vp->tx_skb); /* Release the transferred buffer */
-				if (inw(ioaddr + TxFree) > 1536) {
+				if (ioread16(ioaddr + TxFree) > 1536) {
 					/*
 					 * AKPM: FIXME: I don't think we need this.  If the queue was stopped due to
 					 * insufficient FIFO room, the TxAvailable test will succeed and call
@@ -2367,7 +2371,7 @@ vortex_interrupt(int irq, void *dev_id, 
 					 */
 					netif_wake_queue(dev);
 				} else { /* Interrupt when FIFO has room for max-sized packet. */
-					outw(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
+					iowrite16(SetTxThreshold + (1536>>2), ioaddr + EL3_CMD);
 					netif_stop_queue(dev);
 				}
 			}
@@ -2385,17 +2389,17 @@ vortex_interrupt(int irq, void *dev_id, 
 			/* Disable all pending interrupts. */
 			do {
 				vp->deferred |= status;
-				outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+				iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
 					 ioaddr + EL3_CMD);
-				outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
-			} while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+				iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+			} while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
 			/* The timer will reenable interrupts. */
 			mod_timer(&vp->timer, jiffies + 1*HZ);
 			break;
 		}
 		/* Acknowledge the IRQ. */
-		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
-	} while ((status = inw(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
+		iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+	} while ((status = ioread16(ioaddr + EL3_STATUS)) & (IntLatch | RxComplete));
 
 	if (vortex_debug > 4)
 		printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2415,11 +2419,11 @@ boomerang_interrupt(int irq, void *dev_i
 {
 	struct net_device *dev = dev_id;
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr;
+	void __iomem *ioaddr;
 	int status;
 	int work_done = max_interrupt_work;
 
-	ioaddr = dev->base_addr;
+	ioaddr = vp->ioaddr;
 
 	/*
 	 * It seems dopey to put the spinlock this early, but we could race against vortex_tx_timeout
@@ -2427,7 +2431,7 @@ boomerang_interrupt(int irq, void *dev_i
 	 */
 	spin_lock(&vp->lock);
 
-	status = inw(ioaddr + EL3_STATUS);
+	status = ioread16(ioaddr + EL3_STATUS);
 
 	if (vortex_debug > 6)
 		printk(KERN_DEBUG "boomerang_interrupt. status=0x%4x\n", status);
@@ -2448,13 +2452,13 @@ boomerang_interrupt(int irq, void *dev_i
 
 	if (vortex_debug > 4)
 		printk(KERN_DEBUG "%s: interrupt, status %4.4x, latency %d ticks.\n",
-			   dev->name, status, inb(ioaddr + Timer));
+			   dev->name, status, ioread8(ioaddr + Timer));
 	do {
 		if (vortex_debug > 5)
 				printk(KERN_DEBUG "%s: In interrupt loop, status %4.4x.\n",
 					   dev->name, status);
 		if (status & UpComplete) {
-			outw(AckIntr | UpComplete, ioaddr + EL3_CMD);
+			iowrite16(AckIntr | UpComplete, ioaddr + EL3_CMD);
 			if (vortex_debug > 5)
 				printk(KERN_DEBUG "boomerang_interrupt->boomerang_rx\n");
 			boomerang_rx(dev);
@@ -2463,11 +2467,11 @@ boomerang_interrupt(int irq, void *dev_i
 		if (status & DownComplete) {
 			unsigned int dirty_tx = vp->dirty_tx;
 
-			outw(AckIntr | DownComplete, ioaddr + EL3_CMD);
+			iowrite16(AckIntr | DownComplete, ioaddr + EL3_CMD);
 			while (vp->cur_tx - dirty_tx > 0) {
 				int entry = dirty_tx % TX_RING_SIZE;
 #if 1	/* AKPM: the latter is faster, but cyclone-only */
-				if (inl(ioaddr + DownListPtr) ==
+				if (ioread32(ioaddr + DownListPtr) ==
 					vp->tx_ring_dma + entry * sizeof(struct boom_tx_desc))
 					break;			/* It still hasn't been processed. */
 #else
@@ -2514,20 +2518,20 @@ boomerang_interrupt(int irq, void *dev_i
 			/* Disable all pending interrupts. */
 			do {
 				vp->deferred |= status;
-				outw(SetStatusEnb | (~vp->deferred & vp->status_enable),
+				iowrite16(SetStatusEnb | (~vp->deferred & vp->status_enable),
 					 ioaddr + EL3_CMD);
-				outw(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
-			} while ((status = inw(ioaddr + EL3_CMD)) & IntLatch);
+				iowrite16(AckIntr | (vp->deferred & 0x7ff), ioaddr + EL3_CMD);
+			} while ((status = ioread16(ioaddr + EL3_CMD)) & IntLatch);
 			/* The timer will reenable interrupts. */
 			mod_timer(&vp->timer, jiffies + 1*HZ);
 			break;
 		}
 		/* Acknowledge the IRQ. */
-		outw(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
+		iowrite16(AckIntr | IntReq | IntLatch, ioaddr + EL3_CMD);
 		if (vp->cb_fn_base)			/* The PCMCIA people are idiots.  */
-			writel(0x8000, vp->cb_fn_base + 4);
+			iowrite32(0x8000, vp->cb_fn_base + 4);
 
-	} while ((status = inw(ioaddr + EL3_STATUS)) & IntLatch);
+	} while ((status = ioread16(ioaddr + EL3_STATUS)) & IntLatch);
 
 	if (vortex_debug > 4)
 		printk(KERN_DEBUG "%s: exiting interrupt, status %4.4x.\n",
@@ -2540,16 +2544,16 @@ handler_exit:
 static int vortex_rx(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int i;
 	short rx_status;
 
 	if (vortex_debug > 5)
 		printk(KERN_DEBUG "vortex_rx(): status %4.4x, rx_status %4.4x.\n",
-			   inw(ioaddr+EL3_STATUS), inw(ioaddr+RxStatus));
-	while ((rx_status = inw(ioaddr + RxStatus)) > 0) {
+			   ioread16(ioaddr+EL3_STATUS), ioread16(ioaddr+RxStatus));
+	while ((rx_status = ioread16(ioaddr + RxStatus)) > 0) {
 		if (rx_status & 0x4000) { /* Error, update stats. */
-			unsigned char rx_error = inb(ioaddr + RxErrors);
+			unsigned char rx_error = ioread8(ioaddr + RxErrors);
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG " Rx error: status %2.2x.\n", rx_error);
 			vp->stats.rx_errors++;
@@ -2572,27 +2576,28 @@ static int vortex_rx(struct net_device *
 				skb_reserve(skb, 2);	/* Align IP on 16 byte boundaries */
 				/* 'skb_put()' points to the start of sk_buff data area. */
 				if (vp->bus_master &&
-					! (inw(ioaddr + Wn7_MasterStatus) & 0x8000)) {
+					! (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)) {
 					dma_addr_t dma = pci_map_single(VORTEX_PCI(vp), skb_put(skb, pkt_len),
 									   pkt_len, PCI_DMA_FROMDEVICE);
-					outl(dma, ioaddr + Wn7_MasterAddr);
-					outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
-					outw(StartDMAUp, ioaddr + EL3_CMD);
-					while (inw(ioaddr + Wn7_MasterStatus) & 0x8000)
+					iowrite32(dma, ioaddr + Wn7_MasterAddr);
+					iowrite16((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen);
+					iowrite16(StartDMAUp, ioaddr + EL3_CMD);
+					while (ioread16(ioaddr + Wn7_MasterStatus) & 0x8000)
 						;
 					pci_unmap_single(VORTEX_PCI(vp), dma, pkt_len, PCI_DMA_FROMDEVICE);
 				} else {
-					insl(ioaddr + RX_FIFO, skb_put(skb, pkt_len),
-						 (pkt_len + 3) >> 2);
+					ioread32_rep(ioaddr + RX_FIFO,
+					             skb_put(skb, pkt_len),
+						     (pkt_len + 3) >> 2);
 				}
-				outw(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
+				iowrite16(RxDiscard, ioaddr + EL3_CMD); /* Pop top Rx packet. */
 				skb->protocol = eth_type_trans(skb, dev);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
 				vp->stats.rx_packets++;
 				/* Wait a limited time to go to next packet. */
 				for (i = 200; i >= 0; i--)
-					if ( ! (inw(ioaddr + EL3_STATUS) & CmdInProgress))
+					if ( ! (ioread16(ioaddr + EL3_STATUS) & CmdInProgress))
 						break;
 				continue;
 			} else if (vortex_debug > 0)
@@ -2611,12 +2616,12 @@ boomerang_rx(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
 	int entry = vp->cur_rx % RX_RING_SIZE;
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int rx_status;
 	int rx_work_limit = vp->dirty_rx + RX_RING_SIZE - vp->cur_rx;
 
 	if (vortex_debug > 5)
-		printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", inw(ioaddr+EL3_STATUS));
+		printk(KERN_DEBUG "boomerang_rx(): status %4.4x\n", ioread16(ioaddr+EL3_STATUS));
 
 	while ((rx_status = le32_to_cpu(vp->rx_ring[entry].status)) & RxDComplete){
 		if (--rx_work_limit < 0)
@@ -2699,7 +2704,7 @@ boomerang_rx(struct net_device *dev)
 			vp->rx_skbuff[entry] = skb;
 		}
 		vp->rx_ring[entry].status = 0;	/* Clear complete bit. */
-		outw(UpUnstall, ioaddr + EL3_CMD);
+		iowrite16(UpUnstall, ioaddr + EL3_CMD);
 	}
 	return 0;
 }
@@ -2728,7 +2733,7 @@ static void
 vortex_down(struct net_device *dev, int final_down)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 
 	netif_stop_queue (dev);
 
@@ -2736,26 +2741,26 @@ vortex_down(struct net_device *dev, int 
 	del_timer_sync(&vp->timer);
 
 	/* Turn off statistics ASAP.  We update vp->stats below. */
-	outw(StatsDisable, ioaddr + EL3_CMD);
+	iowrite16(StatsDisable, ioaddr + EL3_CMD);
 
 	/* Disable the receiver and transmitter. */
-	outw(RxDisable, ioaddr + EL3_CMD);
-	outw(TxDisable, ioaddr + EL3_CMD);
+	iowrite16(RxDisable, ioaddr + EL3_CMD);
+	iowrite16(TxDisable, ioaddr + EL3_CMD);
 
 	/* Disable receiving 802.1q tagged frames */
 	set_8021q_mode(dev, 0);
 
 	if (dev->if_port == XCVR_10base2)
 		/* Turn off thinnet power.  Green! */
-		outw(StopCoax, ioaddr + EL3_CMD);
+		iowrite16(StopCoax, ioaddr + EL3_CMD);
 
-	outw(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
+	iowrite16(SetIntrEnb | 0x0000, ioaddr + EL3_CMD);
 
 	update_stats(ioaddr, dev);
 	if (vp->full_bus_master_rx)
-		outl(0, ioaddr + UpListPtr);
+		iowrite32(0, ioaddr + UpListPtr);
 	if (vp->full_bus_master_tx)
-		outl(0, ioaddr + DownListPtr);
+		iowrite32(0, ioaddr + DownListPtr);
 
 	if (final_down && VORTEX_PCI(vp)) {
 		vp->pm_state_valid = 1;
@@ -2768,7 +2773,7 @@ static int
 vortex_close(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	int i;
 
 	if (netif_device_present(dev))
@@ -2776,7 +2781,7 @@ vortex_close(struct net_device *dev)
 
 	if (vortex_debug > 1) {
 		printk(KERN_DEBUG"%s: vortex_close() status %4.4x, Tx status %2.2x.\n",
-			   dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TxStatus));
+			   dev->name, ioread16(ioaddr + EL3_STATUS), ioread8(ioaddr + TxStatus));
 		printk(KERN_DEBUG "%s: vortex close stats: rx_nocopy %d rx_copy %d"
 			   " tx_queued %d Rx pre-checksummed %d.\n",
 			   dev->name, vp->rx_nocopy, vp->rx_copy, vp->queued_packet, vp->rx_csumhits);
@@ -2830,18 +2835,18 @@ dump_tx_ring(struct net_device *dev)
 {
 	if (vortex_debug > 0) {
 	struct vortex_private *vp = netdev_priv(dev);
-		long ioaddr = dev->base_addr;
+		void __iomem *ioaddr = vp->ioaddr;
 		
 		if (vp->full_bus_master_tx) {
 			int i;
-			int stalled = inl(ioaddr + PktStatus) & 0x04;	/* Possible racy. But it's only debug stuff */
+			int stalled = ioread32(ioaddr + PktStatus) & 0x04;	/* Possible racy. But it's only debug stuff */
 
 			printk(KERN_ERR "  Flags; bus-master %d, dirty %d(%d) current %d(%d)\n",
 					vp->full_bus_master_tx,
 					vp->dirty_tx, vp->dirty_tx % TX_RING_SIZE,
 					vp->cur_tx, vp->cur_tx % TX_RING_SIZE);
 			printk(KERN_ERR "  Transmit list %8.8x vs. %p.\n",
-				   inl(ioaddr + DownListPtr),
+				   ioread32(ioaddr + DownListPtr),
 				   &vp->tx_ring[vp->dirty_tx % TX_RING_SIZE]);
 			issue_and_wait(dev, DownStall);
 			for (i = 0; i < TX_RING_SIZE; i++) {
@@ -2855,7 +2860,7 @@ dump_tx_ring(struct net_device *dev)
 					   le32_to_cpu(vp->tx_ring[i].status));
 			}
 			if (!stalled)
-				outw(DownUnstall, ioaddr + EL3_CMD);
+				iowrite16(DownUnstall, ioaddr + EL3_CMD);
 		}
 	}
 }
@@ -2863,11 +2868,12 @@ dump_tx_ring(struct net_device *dev)
 static struct net_device_stats *vortex_get_stats(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 
 	if (netif_device_present(dev)) {	/* AKPM: Used to be netif_running */
 		spin_lock_irqsave (&vp->lock, flags);
-		update_stats(dev->base_addr, dev);
+		update_stats(ioaddr, dev);
 		spin_unlock_irqrestore (&vp->lock, flags);
 	}
 	return &vp->stats;
@@ -2880,37 +2886,37 @@ static struct net_device_stats *vortex_g
 	table.  This is done by checking that the ASM (!) code generated uses
 	atomic updates with '+='.
 	*/
-static void update_stats(long ioaddr, struct net_device *dev)
+static void update_stats(void __iomem *ioaddr, struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	int old_window = inw(ioaddr + EL3_CMD);
+	int old_window = ioread16(ioaddr + EL3_CMD);
 
 	if (old_window == 0xffff)	/* Chip suspended or ejected. */
 		return;
 	/* Unlike the 3c5x9 we need not turn off stats updates while reading. */
 	/* Switch to the stats window, and read everything. */
 	EL3WINDOW(6);
-	vp->stats.tx_carrier_errors		+= inb(ioaddr + 0);
-	vp->stats.tx_heartbeat_errors		+= inb(ioaddr + 1);
-	vp->stats.collisions			+= inb(ioaddr + 3);
-	vp->stats.tx_window_errors		+= inb(ioaddr + 4);
-	vp->stats.rx_fifo_errors		+= inb(ioaddr + 5);
-	vp->stats.tx_packets			+= inb(ioaddr + 6);
-	vp->stats.tx_packets			+= (inb(ioaddr + 9)&0x30) << 4;
-	/* Rx packets	*/			inb(ioaddr + 7);   /* Must read to clear */
+	vp->stats.tx_carrier_errors		+= ioread8(ioaddr + 0);
+	vp->stats.tx_heartbeat_errors		+= ioread8(ioaddr + 1);
+	vp->stats.collisions			+= ioread8(ioaddr + 3);
+	vp->stats.tx_window_errors		+= ioread8(ioaddr + 4);
+	vp->stats.rx_fifo_errors		+= ioread8(ioaddr + 5);
+	vp->stats.tx_packets			+= ioread8(ioaddr + 6);
+	vp->stats.tx_packets			+= (ioread8(ioaddr + 9)&0x30) << 4;
+	/* Rx packets	*/			ioread8(ioaddr + 7);   /* Must read to clear */
 	/* Don't bother with register 9, an extension of registers 6&7.
 	   If we do use the 6&7 values the atomic update assumption above
 	   is invalid. */
-	vp->stats.rx_bytes 			+= inw(ioaddr + 10);
-	vp->stats.tx_bytes 			+= inw(ioaddr + 12);
+	vp->stats.rx_bytes 			+= ioread16(ioaddr + 10);
+	vp->stats.tx_bytes 			+= ioread16(ioaddr + 12);
 	/* Extra stats for get_ethtool_stats() */
-	vp->xstats.tx_multiple_collisions	+= inb(ioaddr + 2);
-	vp->xstats.tx_deferred			+= inb(ioaddr + 8);
+	vp->xstats.tx_multiple_collisions	+= ioread8(ioaddr + 2);
+	vp->xstats.tx_deferred			+= ioread8(ioaddr + 8);
 	EL3WINDOW(4);
-	vp->xstats.rx_bad_ssd			+= inb(ioaddr + 12);
+	vp->xstats.rx_bad_ssd			+= ioread8(ioaddr + 12);
 
 	{
-		u8 up = inb(ioaddr + 13);
+		u8 up = ioread8(ioaddr + 13);
 		vp->stats.rx_bytes += (up & 0x0f) << 16;
 		vp->stats.tx_bytes += (up & 0xf0) << 12;
 	}
@@ -2922,7 +2928,7 @@ static void update_stats(long ioaddr, st
 static int vortex_nway_reset(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int rc;
 
@@ -2936,7 +2942,7 @@ static int vortex_nway_reset(struct net_
 static u32 vortex_get_link(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int rc;
 
@@ -2950,7 +2956,7 @@ static u32 vortex_get_link(struct net_de
 static int vortex_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int rc;
 
@@ -2964,7 +2970,7 @@ static int vortex_get_settings(struct ne
 static int vortex_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int rc;
 
@@ -2994,10 +3000,11 @@ static void vortex_get_ethtool_stats(str
 	struct ethtool_stats *stats, u64 *data)
 {
 	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 
 	spin_lock_irqsave(&vp->lock, flags);
-	update_stats(dev->base_addr, dev);
+	update_stats(ioaddr, dev);
 	spin_unlock_irqrestore(&vp->lock, flags);
 
 	data[0] = vp->xstats.tx_deferred;
@@ -3057,7 +3064,7 @@ static int vortex_ioctl(struct net_devic
 {
 	int err;
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 	unsigned long flags;
 	int state = 0;
 
@@ -3085,7 +3092,8 @@ static int vortex_ioctl(struct net_devic
    the chip has a very clean way to set the mode, unlike many others. */
 static void set_rx_mode(struct net_device *dev)
 {
-	long ioaddr = dev->base_addr;
+	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	int new_mode;
 
 	if (dev->flags & IFF_PROMISC) {
@@ -3097,7 +3105,7 @@ static void set_rx_mode(struct net_devic
 	} else
 		new_mode = SetRxFilter | RxStation | RxBroadcast;
 
-	outw(new_mode, ioaddr + EL3_CMD);
+	iowrite16(new_mode, ioaddr + EL3_CMD);
 }
 
 #if defined(CONFIG_VLAN_8021Q) || defined(CONFIG_VLAN_8021Q_MODULE)
@@ -3111,8 +3119,8 @@ static void set_rx_mode(struct net_devic
 static void set_8021q_mode(struct net_device *dev, int enable)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
-	int old_window = inw(ioaddr + EL3_CMD);
+	void __iomem *ioaddr = vp->ioaddr;
+	int old_window = ioread16(ioaddr + EL3_CMD);
 	int mac_ctrl;
 
 	if ((vp->drv_flags&IS_CYCLONE) || (vp->drv_flags&IS_TORNADO)) {
@@ -3124,24 +3132,24 @@ static void set_8021q_mode(struct net_de
 			max_pkt_size += 4;	/* 802.1Q VLAN tag */
 
 		EL3WINDOW(3);
-		outw(max_pkt_size, ioaddr+Wn3_MaxPktSize);
+		iowrite16(max_pkt_size, ioaddr+Wn3_MaxPktSize);
 
 		/* set VlanEtherType to let the hardware checksumming
 		   treat tagged frames correctly */
 		EL3WINDOW(7);
-		outw(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
+		iowrite16(VLAN_ETHER_TYPE, ioaddr+Wn7_VlanEtherType);
 	} else {
 		/* on older cards we have to enable large frames */
 
 		vp->large_frames = dev->mtu > 1500 || enable;
 
 		EL3WINDOW(3);
-		mac_ctrl = inw(ioaddr+Wn3_MAC_Ctrl);
+		mac_ctrl = ioread16(ioaddr+Wn3_MAC_Ctrl);
 		if (vp->large_frames)
 			mac_ctrl |= 0x40;
 		else
 			mac_ctrl &= ~0x40;
-		outw(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
+		iowrite16(mac_ctrl, ioaddr+Wn3_MAC_Ctrl);
 	}
 
 	EL3WINDOW(old_window);
@@ -3163,7 +3171,7 @@ static void set_8021q_mode(struct net_de
 /* The maximum data clock rate is 2.5 Mhz.  The minimum timing is usually
    met by back-to-back PCI I/O cycles, but we insert a delay to avoid
    "overclocking" issues. */
-#define mdio_delay() inl(mdio_addr)
+#define mdio_delay() ioread32(mdio_addr)
 
 #define MDIO_SHIFT_CLK	0x01
 #define MDIO_DIR_WRITE	0x04
@@ -3174,15 +3182,15 @@ static void set_8021q_mode(struct net_de
 
 /* Generate the preamble required for initial synchronization and
    a few older transceivers. */
-static void mdio_sync(long ioaddr, int bits)
+static void mdio_sync(void __iomem *ioaddr, int bits)
 {
-	long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+	void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
 	/* Establish sync by sending at least 32 logic ones. */
 	while (-- bits >= 0) {
-		outw(MDIO_DATA_WRITE1, mdio_addr);
+		iowrite16(MDIO_DATA_WRITE1, mdio_addr);
 		mdio_delay();
-		outw(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
+		iowrite16(MDIO_DATA_WRITE1 | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 }
@@ -3190,10 +3198,11 @@ static void mdio_sync(long ioaddr, int b
 static int mdio_read(struct net_device *dev, int phy_id, int location)
 {
 	int i;
-	long ioaddr = dev->base_addr;
+	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	int read_cmd = (0xf6 << 10) | (phy_id << 5) | location;
 	unsigned int retval = 0;
-	long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+	void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 
 	if (mii_preamble_required)
 		mdio_sync(ioaddr, 32);
@@ -3201,17 +3210,17 @@ static int mdio_read(struct net_device *
 	/* Shift the read command bits out. */
 	for (i = 14; i >= 0; i--) {
 		int dataval = (read_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-		outw(dataval, mdio_addr);
+		iowrite16(dataval, mdio_addr);
 		mdio_delay();
-		outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
+		iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 	/* Read the two transition, 16 data, and wire-idle bits. */
 	for (i = 19; i > 0; i--) {
-		outw(MDIO_ENB_IN, mdio_addr);
+		iowrite16(MDIO_ENB_IN, mdio_addr);
 		mdio_delay();
-		retval = (retval << 1) | ((inw(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
-		outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+		retval = (retval << 1) | ((ioread16(mdio_addr) & MDIO_DATA_READ) ? 1 : 0);
+		iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 	return retval & 0x20000 ? 0xffff : retval>>1 & 0xffff;
@@ -3219,9 +3228,10 @@ static int mdio_read(struct net_device *
 
 static void mdio_write(struct net_device *dev, int phy_id, int location, int value)
 {
-	long ioaddr = dev->base_addr;
+	struct vortex_private *vp = netdev_priv(dev);
+	void __iomem *ioaddr = vp->ioaddr;
 	int write_cmd = 0x50020000 | (phy_id << 23) | (location << 18) | value;
-	long mdio_addr = ioaddr + Wn4_PhysicalMgmt;
+	void __iomem *mdio_addr = ioaddr + Wn4_PhysicalMgmt;
 	int i;
 
 	if (mii_preamble_required)
@@ -3230,16 +3240,16 @@ static void mdio_write(struct net_device
 	/* Shift the command bits out. */
 	for (i = 31; i >= 0; i--) {
 		int dataval = (write_cmd&(1<<i)) ? MDIO_DATA_WRITE1 : MDIO_DATA_WRITE0;
-		outw(dataval, mdio_addr);
+		iowrite16(dataval, mdio_addr);
 		mdio_delay();
-		outw(dataval | MDIO_SHIFT_CLK, mdio_addr);
+		iowrite16(dataval | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 	/* Leave the interface idle. */
 	for (i = 1; i >= 0; i--) {
-		outw(MDIO_ENB_IN, mdio_addr);
+		iowrite16(MDIO_ENB_IN, mdio_addr);
 		mdio_delay();
-		outw(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
+		iowrite16(MDIO_ENB_IN | MDIO_SHIFT_CLK, mdio_addr);
 		mdio_delay();
 	}
 	return;
@@ -3250,15 +3260,15 @@ static void mdio_write(struct net_device
 static void acpi_set_WOL(struct net_device *dev)
 {
 	struct vortex_private *vp = netdev_priv(dev);
-	long ioaddr = dev->base_addr;
+	void __iomem *ioaddr = vp->ioaddr;
 
 	if (vp->enable_wol) {
 		/* Power up on: 1==Downloaded Filter, 2==Magic Packets, 4==Link Status. */
 		EL3WINDOW(7);
-		outw(2, ioaddr + 0x0c);
+		iowrite16(2, ioaddr + 0x0c);
 		/* The RxFilter must accept the WOL frames. */
-		outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
-		outw(RxEnable, ioaddr + EL3_CMD);
+		iowrite16(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD);
+		iowrite16(RxEnable, ioaddr + EL3_CMD);
 
 		pci_enable_wake(VORTEX_PCI(vp), 0, 1);
 
@@ -3280,10 +3290,9 @@ static void __devexit vortex_remove_one 
 
 	vp = netdev_priv(dev);
 
-	/* AKPM: FIXME: we should have
-	 *	if (vp->cb_fn_base) iounmap(vp->cb_fn_base);
-	 * here
-	 */
+	if (vp->cb_fn_base)
+		pci_iounmap(VORTEX_PCI(vp), vp->cb_fn_base);
+
 	unregister_netdev(dev);
 
 	if (VORTEX_PCI(vp)) {
@@ -3293,8 +3302,10 @@ static void __devexit vortex_remove_one 
 		pci_disable_device(VORTEX_PCI(vp));
 	}
 	/* Should really use issue_and_wait() here */
-	outw(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
-	     dev->base_addr + EL3_CMD);
+	iowrite16(TotalReset | ((vp->drv_flags & EEPROM_RESET) ? 0x04 : 0x14),
+	     vp->ioaddr + EL3_CMD);
+
+	pci_iounmap(VORTEX_PCI(vp), vp->ioaddr);
 
 	pci_free_consistent(pdev,
 						sizeof(struct boom_rx_desc) * RX_RING_SIZE
@@ -3342,7 +3353,7 @@ static int __init vortex_init (void)
 static void __exit vortex_eisa_cleanup (void)
 {
 	struct vortex_private *vp;
-	long ioaddr;
+	void __iomem *ioaddr;
 
 #ifdef CONFIG_EISA
 	/* Take care of the EISA devices */
@@ -3351,11 +3362,13 @@ static void __exit vortex_eisa_cleanup (
 	
 	if (compaq_net_device) {
 		vp = compaq_net_device->priv;
-		ioaddr = compaq_net_device->base_addr;
+		ioaddr = ioport_map(compaq_net_device->base_addr,
+		                    VORTEX_TOTAL_SIZE);
 
 		unregister_netdev (compaq_net_device);
-		outw (TotalReset, ioaddr + EL3_CMD);
-		release_region (ioaddr, VORTEX_TOTAL_SIZE);
+		iowrite16 (TotalReset, ioaddr + EL3_CMD);
+		release_region(compaq_net_device->base_addr,
+		               VORTEX_TOTAL_SIZE);
 
 		free_netdev (compaq_net_device);
 	}
---
0.99.8.GIT


--- NEW FILE 2613-3c59x-cleanup-of-mdio_read-routines-to-use-MII_-macros.txt ---
Subject: [PATCH] 3c59x: cleanup of mdio_read routines to use MII_* macros
From: Neil Horman <nhorman at tuxdriver.com>
Date: 1131353883 -0800

Clean up mdio_read routines in 3c59x.c to use the MII_* macros defined in
include/linux/mii.h

Signed-off-by: Neil Horman <nhorman at tuxdriver.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |   16 ++++++++--------
 1 files changed, 8 insertions(+), 8 deletions(-)

applies-to: a5a9a02a8748d96f3b9a3127058776b732b17b6b
106427e65d2b6f3a519ab5d14a3586007e7e0f20
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 2bad41b..88ce4c4 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1457,7 +1457,7 @@ static int __devinit vortex_probe1(struc
 		if (vp->drv_flags & EXTRA_PREAMBLE)
 			mii_preamble_required++;
 		mdio_sync(ioaddr, 32);
-		mdio_read(dev, 24, 1);
+		mdio_read(dev, 24, MII_BMSR);
 		for (phy = 0; phy < 32 && phy_idx < 1; phy++) {
 			int mii_status, phyx;
 
@@ -1471,7 +1471,7 @@ static int __devinit vortex_probe1(struc
 				phyx = phy - 1;
 			else
 				phyx = phy;
-			mii_status = mdio_read(dev, phyx, 1);
+			mii_status = mdio_read(dev, phyx, MII_BMSR);
 			if (mii_status  &&  mii_status != 0xffff) {
 				vp->phys[phy_idx++] = phyx;
 				if (print_info) {
@@ -1487,7 +1487,7 @@ static int __devinit vortex_probe1(struc
 			printk(KERN_WARNING"  ***WARNING*** No MII transceivers found!\n");
 			vp->phys[0] = 24;
 		} else {
-			vp->advertising = mdio_read(dev, vp->phys[0], 4);
+			vp->advertising = mdio_read(dev, vp->phys[0], MII_ADVERTISE);
 			if (vp->full_duplex) {
 				/* Only advertise the FD media types. */
 				vp->advertising &= ~0x02A0;
@@ -1661,8 +1661,8 @@ vortex_up(struct net_device *dev)
 		int mii_reg1, mii_reg5;
 		EL3WINDOW(4);
 		/* Read BMSR (reg1) only to clear old status. */
-		mii_reg1 = mdio_read(dev, vp->phys[0], 1);
-		mii_reg5 = mdio_read(dev, vp->phys[0], 5);
+		mii_reg1 = mdio_read(dev, vp->phys[0], MII_BMSR);
+		mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
 		if (mii_reg5 == 0xffff  ||  mii_reg5 == 0x0000) {
 			netif_carrier_off(dev); /* No MII device or no link partner report */
 		} else {
@@ -1892,14 +1892,14 @@ vortex_timer(unsigned long data)
 	case XCVR_MII: case XCVR_NWAY:
 		{
 			spin_lock_bh(&vp->lock);
-			mii_status = mdio_read(dev, vp->phys[0], 1);
-			mii_status = mdio_read(dev, vp->phys[0], 1);
+			mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
+			mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
 			ok = 1;
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n",
 					dev->name, mii_status);
 			if (mii_status & BMSR_LSTATUS) {
-				int mii_reg5 = mdio_read(dev, vp->phys[0], 5);
+				int mii_reg5 = mdio_read(dev, vp->phys[0], MII_LPA);
 				if (! vp->force_fd  &&  mii_reg5 != 0xffff) {
 					int duplex;
 
---
0.99.8.GIT


--- NEW FILE 2614-3c59x-avoid-blindly-reading-link-status-twice.txt ---
Subject: [PATCH] 3c59x: avoid blindly reading link status twice
From: Tommy Christensen <tommy.christensen at tpack.net>
Date: 1131353884 -0800

In order to spare some I/O operations, be more intelligent about when to
read from the PHY.

Pointed out by Bogdan Costescu.

Signed-off-by: Tommy S. Christensen <tommy.christensen at tpack.net>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |    5 ++++-
 1 files changed, 4 insertions(+), 1 deletions(-)

applies-to: 97c882ac0ffc0e039b26c0b414fcdf382b31d8fd
d9e46de34e4212f472684b1561ba323aac54ea25
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 88ce4c4..e1f773d 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1893,7 +1893,10 @@ vortex_timer(unsigned long data)
 		{
 			spin_lock_bh(&vp->lock);
 			mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
-			mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
+			if (!(mii_status & BMSR_LSTATUS)) {
+				/* Re-read to get actual link status */
+				mii_status = mdio_read(dev, vp->phys[0], MII_BMSR);
+			}
 			ok = 1;
 			if (vortex_debug > 2)
 				printk(KERN_DEBUG "%s: MII transceiver has status %4.4x.\n",
---
0.99.8.GIT


--- NEW FILE 2615-3c59x-bounds-checking-for-hw_checksums.txt ---
Subject: [PATCH] 3c59x: bounds checking for hw_checksums
From: John W. Linville <linville at tuxdriver.com>
Date: 1131353885 -0800

Add bounds checking to usage of hw_checksums module parameter array.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |   16 +++++++++-------
 1 files changed, 9 insertions(+), 7 deletions(-)

applies-to: bf8392ea5f243cc5ddbd32c82dec144ba82d036b
32fb5f06dbb6ca007f7886eb210b7b15545e2e15
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index e1f773d..78f90eb 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1513,9 +1513,10 @@ static int __devinit vortex_probe1(struc
 		dev->hard_start_xmit = boomerang_start_xmit;
 		/* Actually, it still should work with iommu. */
 		dev->features |= NETIF_F_SG;
-		if (((hw_checksums[card_idx] == -1) && (vp->drv_flags & HAS_HWCKSM)) ||
-					(hw_checksums[card_idx] == 1)) {
-				dev->features |= NETIF_F_IP_CSUM;
+		if (card_idx < MAX_UNITS &&
+		    ((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
+				hw_checksums[card_idx] == 1)) {
+			dev->features |= NETIF_F_IP_CSUM;
 		}
 	} else {
 		dev->hard_start_xmit = vortex_start_xmit;
@@ -2791,10 +2792,11 @@ vortex_close(struct net_device *dev)
 	}
 
 #if DO_ZEROCOPY
-	if (	vp->rx_csumhits &&
-			((vp->drv_flags & HAS_HWCKSM) == 0) &&
-			(hw_checksums[vp->card_idx] == -1)) {
-		printk(KERN_WARNING "%s supports hardware checksums, and we're not using them!\n", dev->name);
+	if (vp->rx_csumhits &&
+	    (vp->drv_flags & HAS_HWCKSM) == 0 &&
+	    (vp->card_idx >= MAX_UNITS || hw_checksums[vp->card_idx] == -1)) {
+			printk(KERN_WARNING "%s supports hardware checksums, and we're "
+						"not using them!\n", dev->name);
 	}
 #endif
 		
---
0.99.8.GIT


--- NEW FILE 2616-3c59x-cleanup-init-of-module-parameter-arrays.txt ---
Subject: [PATCH] 3c59x: cleanup init of module parameter arrays
From: John W. Linville <linville at tuxdriver.com>
Date: 1131353886 -0800

Beautify the array initilizations for the module parameters.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

applies-to: c9a35e47f42aa54645f98d1e4d8e9d73ce411d19
9954ab7fd52afedf0977893352bb3ddb07120214
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 78f90eb..0139d4b 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -903,11 +903,11 @@ static void set_8021q_mode(struct net_de
 /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */
 /* Option count limit only -- unlimited interfaces are supported. */
 #define MAX_UNITS 8
-static int options[MAX_UNITS] = { -1, -1, -1, -1, -1, -1, -1, -1,};
-static int full_duplex[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int hw_checksums[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int flow_ctrl[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
-static int enable_wol[MAX_UNITS] = {-1, -1, -1, -1, -1, -1, -1, -1};
+static int options[MAX_UNITS] = { [0 ... MAX_UNITS-1] = -1 };
+static int full_duplex[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int hw_checksums[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int flow_ctrl[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int enable_wol[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
 static int global_options = -1;
 static int global_full_duplex = -1;
 static int global_enable_wol = -1;
---
0.99.8.GIT


--- NEW FILE 2617-3c59x-fix-some-grammar-in-module-parameter-descriptions.txt ---
Subject: [PATCH] 3c59x: fix some grammar in module parameter descriptions
From: John W. Linville <linville at tuxdriver.com>
Date: 1131353886 -0800

Correct several (apparently cut & paste) grammatical typos in module
parameter descriptions.  They seem to have originated as copies of the
description for "global_options".

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

applies-to: 84a256331fc03514d3a29c3828aad725d7d9474c
46e5e4a897ade416beb0bd8447fb0ff0bc1bb329
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 0139d4b..7dcc554 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -939,11 +939,11 @@ MODULE_PARM_DESC(debug, "3c59x debug lev
 MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
 MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
 MODULE_PARM_DESC(full_duplex, "3c59x full duplex setting(s) (1)");
-MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(global_full_duplex, "3c59x: same as full_duplex, but applies to all NICs if full_duplex is unset");
 MODULE_PARM_DESC(hw_checksums, "3c59x Hardware checksum checking by adapter(s) (0-1)");
 MODULE_PARM_DESC(flow_ctrl, "3c59x 802.3x flow control usage (PAUSE only) (0-1)");
 MODULE_PARM_DESC(enable_wol, "3c59x: Turn on Wake-on-LAN for adapter(s) (0-1)");
-MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(global_enable_wol, "3c59x: same as enable_wol, but applies to all NICs if enable_wol is unset");
 MODULE_PARM_DESC(rx_copybreak, "3c59x copy breakpoint for copy-only-tiny-frames");
 MODULE_PARM_DESC(max_interrupt_work, "3c59x maximum events handled per interrupt");
 MODULE_PARM_DESC(compaq_ioaddr, "3c59x PCI I/O base address (Compaq BIOS problem workaround)");
---
0.99.8.GIT


--- NEW FILE 2618-3c59x-support-ETHTOOL_GPERMADDR.txt ---
Subject: [PATCH] 3c59x: support ETHTOOL_GPERMADDR
From: John W. Linville <linville at tuxdriver.com>
Date: 1131353887 -0800

Add support for ETHTOOL_GPERMADDR to 3c59x.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: 2a450817346165ff95e5f8aa040da755b7f7074c
bb531fc071f9017b4809c806f71e6a7f49b67289
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 7dcc554..be4f962 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1341,6 +1341,7 @@ static int __devinit vortex_probe1(struc
 		printk(" ***INVALID CHECKSUM %4.4x*** ", checksum);
 	for (i = 0; i < 3; i++)
 		((u16 *)dev->dev_addr)[i] = htons(eeprom[i + 10]);
+	memcpy(dev->perm_addr, dev->dev_addr, dev->addr_len);
 	if (print_info) {
 		for (i = 0; i < 6; i++)
 			printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]);
@@ -3059,6 +3060,7 @@ static struct ethtool_ops vortex_ethtool
 	.set_settings           = vortex_set_settings,
 	.get_link               = vortex_get_link,
 	.nway_reset             = vortex_nway_reset,
+	.get_perm_addr			= ethtool_op_get_perm_addr,
 };
 
 #ifdef CONFIG_PCI
---
0.99.8.GIT


--- NEW FILE 2619-3c59x-correct-rx_dropped-counting.txt ---
Subject: [PATCH] 3c59x: correct rx_dropped counting
From: John W. Linville <linville at tuxdriver.com>
Date: 1131353888 -0800

Only increment rx_dropped in case of lack of resources (i.e. not for
frames with errors).

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 7ea3624e9dc8235eb47cec781c8117367eaeb9f6
35b306743d17cdd31357e5de9ce6c549e5d6756e
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index be4f962..413b82c 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -2608,8 +2608,8 @@ static int vortex_rx(struct net_device *
 			} else if (vortex_debug > 0)
 				printk(KERN_NOTICE "%s: No memory to allocate a sk_buff of "
 					   "size %d.\n", dev->name, pkt_len);
+			vp->stats.rx_dropped++;
 		}
-		vp->stats.rx_dropped++;
 		issue_and_wait(dev, RxDiscard);
 	}
 
---
0.99.8.GIT


--- NEW FILE 2620-3c59x-enable-use-of-memory-mapped-PCI-I-O.txt ---
Subject: [PATCH] 3c59x: enable use of memory-mapped PCI I/O
From: John W. Linville <linville at tuxdriver.com>
Date: 1131353888 -0800

Add capability for 3c59x driver to use memory-mapped PCI I/O resources.
This may improve performance for those devices so equipped.  This will be
the default behaviour for IS_CYCLONE and IS_TORNADO devices.  Additionally,
it can be enabled/disabled individually for up to MAX_UNITS number of
devices via the use_mmio module option or for all units via the
global_use_mmio option.  The use_mmio option overrides the global_use_mmio
option for those devices specified.

Signed-off-by: John W. Linville <linville at tuxdriver.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |   29 ++++++++++++++++++++++++++---
 1 files changed, 26 insertions(+), 3 deletions(-)

applies-to: 0aa8330f1928313afe819a311e424aed8615bc9c
900fd17dd01d2c99dfd1ec0b53a860894a2673ee
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index 413b82c..c1ee8ef 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -908,9 +908,11 @@ static int full_duplex[MAX_UNITS] = {[0 
 static int hw_checksums[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
 static int flow_ctrl[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
 static int enable_wol[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
+static int use_mmio[MAX_UNITS] = {[0 ... MAX_UNITS-1] = -1 };
 static int global_options = -1;
 static int global_full_duplex = -1;
 static int global_enable_wol = -1;
+static int global_use_mmio = -1;
 
 /* #define dev_alloc_skb dev_alloc_skb_debug */
 
@@ -935,6 +937,8 @@ module_param(compaq_ioaddr, int, 0);
 module_param(compaq_irq, int, 0);
 module_param(compaq_device_id, int, 0);
 module_param(watchdog, int, 0);
+module_param(global_use_mmio, int, 0);
+module_param_array(use_mmio, int, NULL, 0);
 MODULE_PARM_DESC(debug, "3c59x debug level (0-6)");
 MODULE_PARM_DESC(options, "3c59x: Bits 0-3: media type, bit 4: bus mastering, bit 9: full duplex");
 MODULE_PARM_DESC(global_options, "3c59x: same as options, but applies to all NICs if options is unset");
@@ -950,6 +954,8 @@ MODULE_PARM_DESC(compaq_ioaddr, "3c59x P
 MODULE_PARM_DESC(compaq_irq, "3c59x PCI IRQ number (Compaq BIOS problem workaround)");
 MODULE_PARM_DESC(compaq_device_id, "3c59x PCI device ID (Compaq BIOS problem workaround)");
 MODULE_PARM_DESC(watchdog, "3c59x transmit timeout in milliseconds");
+MODULE_PARM_DESC(global_use_mmio, "3c59x: same as use_mmio, but applies to all NICs if options is unset");
+MODULE_PARM_DESC(use_mmio, "3c59x: use memory-mapped PCI I/O resource (0-1)");
 
 #ifdef CONFIG_NET_POLL_CONTROLLER
 static void poll_vortex(struct net_device *dev)
@@ -1109,15 +1115,32 @@ static int __init vortex_eisa_init (void
 static int __devinit vortex_init_one (struct pci_dev *pdev,
 				      const struct pci_device_id *ent)
 {
-	int rc;
+	int rc, unit, pci_bar;
+	struct vortex_chip_info *vci;
+	void __iomem *ioaddr;
 
 	/* wake up and enable device */		
 	rc = pci_enable_device (pdev);
 	if (rc < 0)
 		goto out;
 
-	rc = vortex_probe1 (&pdev->dev, pci_iomap(pdev, 0, 0),
-			    pdev->irq, ent->driver_data, vortex_cards_found);
+	unit = vortex_cards_found;
+
+	if (global_use_mmio < 0 && (unit >= MAX_UNITS || use_mmio[unit] < 0)) {
+		/* Determine the default if the user didn't override us */
+		vci = &vortex_info_tbl[ent->driver_data];
+		pci_bar = vci->drv_flags & (IS_CYCLONE | IS_TORNADO) ? 1 : 0;
+	} else if (unit < MAX_UNITS && use_mmio[unit] >= 0)
+		pci_bar = use_mmio[unit] ? 1 : 0;
+	else
+		pci_bar = global_use_mmio ? 1 : 0;
+
+	ioaddr = pci_iomap(pdev, pci_bar, 0);
+	if (!ioaddr) /* If mapping fails, fall-back to BAR 0... */
+		ioaddr = pci_iomap(pdev, 0, 0);
+
+	rc = vortex_probe1(&pdev->dev, ioaddr, pdev->irq,
+			   ent->driver_data, unit);
 	if (rc < 0) {
 		pci_disable_device (pdev);
 		goto out;
---
0.99.8.GIT


--- NEW FILE 2621-3c59x-don-t-enable-scatter-gather-w-o-checksum-support.txt ---
Subject: [PATCH] 3c59x: don't enable scatter/gather w/o checksum support
From: Stephen Hemminger <shemminger at osdl.org>
Date: 1131353889 -0800

It is not valid to enable scatter/gather without hardware checksum support
of some kind. (akpm: applies only to the old boomerang cards).

Signed-off-by: Stephen Hemminger <shemminger at osdl.org>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/3c59x.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

applies-to: fcd447fc10d1a58c11854e29077417c329afebe7
d311b0d3d8fcc279132f7251704b23ec264a194f
diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c
index c1ee8ef..7488ee7 100644
--- a/drivers/net/3c59x.c
+++ b/drivers/net/3c59x.c
@@ -1536,11 +1536,10 @@ static int __devinit vortex_probe1(struc
 	if (vp->full_bus_master_tx) {
 		dev->hard_start_xmit = boomerang_start_xmit;
 		/* Actually, it still should work with iommu. */
-		dev->features |= NETIF_F_SG;
 		if (card_idx < MAX_UNITS &&
 		    ((hw_checksums[card_idx] == -1 && (vp->drv_flags & HAS_HWCKSM)) ||
 				hw_checksums[card_idx] == 1)) {
-			dev->features |= NETIF_F_IP_CSUM;
+			dev->features |= NETIF_F_IP_CSUM | NETIF_F_SG;
 		}
 	} else {
 		dev->hard_start_xmit = vortex_start_xmit;
---
0.99.8.GIT


--- NEW FILE 2652-uml-fix-UML-network-driver-endianness-bugs.txt ---
Subject: [PATCH] uml: fix UML network driver endianness bugs
From: Bodo Stroesser <bstroesser at fujitsu-siemens.com>
Date: 1131353927 -0800

ifa->ifa_address and ifa->ifa_mask are defined as __u32, but used as if they
were char[4].

Network code uses htons() to convert it.  So UML's method to access these
fields is wrong for bigendians (e.g.  s390)

I replaced bytewise copying by memcpy(), maybe even that might be removed, if
ifa->ifa_address/mask may be used immediately.

Signed-off-by: Bodo Stroesser <bstroesser at fujitsu-siemens.com>
Signed-off-by: Jeff Dike <jdike at addtoit.com>
Cc: Paolo Giarrusso <blaisorblade at yahoo.it>
Cc: <viro at parcelfarce.linux.theplanet.co.uk>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 arch/um/drivers/net_kern.c |   38 +++++++-------------------------------
 arch/um/include/net_user.h |    2 +-
 2 files changed, 8 insertions(+), 32 deletions(-)

applies-to: 5daba11ac90defc604399aa7ff41fa11b8cd088a
0e76422ca5f34bb43b97c0945646ef072bcc1776
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index 721e260..fe865d9 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -96,7 +96,6 @@ irqreturn_t uml_net_interrupt(int irq, v
 static int uml_net_open(struct net_device *dev)
 {
 	struct uml_net_private *lp = dev->priv;
-	char addr[sizeof("255.255.255.255\0")];
 	int err;
 
 	spin_lock(&lp->lock);
@@ -107,7 +106,7 @@ static int uml_net_open(struct net_devic
 	}
 
 	if(!lp->have_mac){
- 		dev_ip_addr(dev, addr, &lp->mac[2]);
+ 		dev_ip_addr(dev, &lp->mac[2]);
  		set_ether_mac(dev, lp->mac);
 	}
 
@@ -664,8 +663,6 @@ static int uml_inetaddr_event(struct not
 			      void *ptr)
 {
 	struct in_ifaddr *ifa = ptr;
-	u32 addr = ifa->ifa_address;
-	u32 netmask = ifa->ifa_mask;
 	struct net_device *dev = ifa->ifa_dev->dev;
 	struct uml_net_private *lp;
 	void (*proc)(unsigned char *, unsigned char *, void *);
@@ -685,14 +682,8 @@ static int uml_inetaddr_event(struct not
 		break;
 	}
 	if(proc != NULL){
-		addr_buf[0] = addr & 0xff;
-		addr_buf[1] = (addr >> 8) & 0xff;
-		addr_buf[2] = (addr >> 16) & 0xff;
-		addr_buf[3] = addr >> 24;
-		netmask_buf[0] = netmask & 0xff;
-		netmask_buf[1] = (netmask >> 8) & 0xff;
-		netmask_buf[2] = (netmask >> 16) & 0xff;
-		netmask_buf[3] = netmask >> 24;
+		memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
+		memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
 		(*proc)(addr_buf, netmask_buf, &lp->user);
 	}
 	return(NOTIFY_DONE);
@@ -774,27 +765,18 @@ int setup_etheraddr(char *str, unsigned 
 	return(1);
 }
 
-void dev_ip_addr(void *d, char *buf, char *bin_buf)
+void dev_ip_addr(void *d, unsigned char *bin_buf)
 {
 	struct net_device *dev = d;
 	struct in_device *ip = dev->ip_ptr;
 	struct in_ifaddr *in;
-	u32 addr;
 
 	if((ip == NULL) || ((in = ip->ifa_list) == NULL)){
 		printk(KERN_WARNING "dev_ip_addr - device not assigned an "
 		       "IP address\n");
 		return;
 	}
-	addr = in->ifa_address;
-	sprintf(buf, "%d.%d.%d.%d", addr & 0xff, (addr >> 8) & 0xff, 
-		(addr >> 16) & 0xff, addr >> 24);
-	if(bin_buf){
-		bin_buf[0] = addr & 0xff;
-		bin_buf[1] = (addr >> 8) & 0xff;
-		bin_buf[2] = (addr >> 16) & 0xff;
-		bin_buf[3] = addr >> 24;
-	}
+	memcpy(bin_buf, &in->ifa_address, sizeof(in->ifa_address));
 }
 
 void set_ether_mac(void *d, unsigned char *addr)
@@ -829,14 +811,8 @@ void iter_addresses(void *d, void (*cb)(
 	if(ip == NULL) return;
 	in = ip->ifa_list;
 	while(in != NULL){
-		address[0] = in->ifa_address & 0xff;
-		address[1] = (in->ifa_address >> 8) & 0xff;
-		address[2] = (in->ifa_address >> 16) & 0xff;
-		address[3] = in->ifa_address >> 24;
-		netmask[0] = in->ifa_mask & 0xff;
-		netmask[1] = (in->ifa_mask >> 8) & 0xff;
-		netmask[2] = (in->ifa_mask >> 16) & 0xff;
-		netmask[3] = in->ifa_mask >> 24;
+		memcpy(address, &in->ifa_address, sizeof(address));
+		memcpy(netmask, &in->ifa_mask, sizeof(netmask));
 		(*cb)(address, netmask, arg);
 		in = in->ifa_next;
 	}
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index 89885a7..800c403 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -25,7 +25,7 @@ struct net_user_info {
 };
 
 extern void ether_user_init(void *data, void *dev);
-extern void dev_ip_addr(void *d, char *buf, char *bin_buf);
+extern void dev_ip_addr(void *d, unsigned char *bin_buf);
 extern void set_ether_mac(void *d, unsigned char *addr);
 extern void iter_addresses(void *d, void (*cb)(unsigned char *, 
 					       unsigned char *, void *), 
---
0.99.8.GIT


--- NEW FILE 2858-m68knommu-FEC-ethernet-header-support-for-the-ColdFire-5208.txt ---
Subject: [PATCH] m68knommu: FEC ethernet header support for the ColdFire 5208
From: Greg Ungerer <gerg at snapgear.com>
Date: 1131336590 +1000

Add support for the new 5208 ColdFire in the FEC ethernet header.
Patch originally from Matt Waddel (from code originally written by
Mike Lavender).

Signed-off-by: Greg Ungerer <gerg at uclinux.com>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/fec.h |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

applies-to: be1626e8cf8f98b2609b1f674976c3e772ff4b04
7a77d918ad8fb152312525b70780f6e0052b3ee3
diff --git a/drivers/net/fec.h b/drivers/net/fec.h
index 045761b..965c5c4 100644
--- a/drivers/net/fec.h
+++ b/drivers/net/fec.h
@@ -1,11 +1,10 @@
 /****************************************************************************/
 
 /*
- *	fec.h  --  Fast Ethernet Controller for Motorola ColdFire 5230,
- *		   5231, 5232, 5234, 5235, 5270, 5271, 5272, 5274, 5275,
- *		   5280 and 5282.
+ *	fec.h  --  Fast Ethernet Controller for Motorola ColdFire SoC
+ *		   processors.
  *
- *	(C) Copyright 2000-2003, Greg Ungerer (gerg at snapgear.com)
+ *	(C) Copyright 2000-2005, Greg Ungerer (gerg at snapgear.com)
  *	(C) Copyright 2000-2001, Lineo (www.lineo.com)
  */
 
@@ -14,7 +13,8 @@
 #define	FEC_H
 /****************************************************************************/
 
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 /*
  *	Just figures, Motorola would have to change the offsets for
  *	registers in the same peripheral device on different models
---
0.99.8.GIT


--- NEW FILE 2859-m68knommu-FEC-ethernet-support-for-the-ColdFire-5208.txt ---
Subject: [PATCH] m68knommu: FEC ethernet support for the ColdFire 5208
From: Greg Ungerer <gerg at snapgear.com>
Date: 1131336590 +1000

Add support for the new 5208 ColdFire (Matt Waddel / Mike Lavender)
Patch originally from Matt Waddel (from code originally written by
Mike Lavender).

I also re-ordered the init code to avoid interrupt lockups on
some platforms (at least the 5275, but others have reported it on
the 5235 as well).

Signed-off-by: Greg Ungerer <gerg at uclinux.com>
Signed-off-by: Linus Torvalds <torvalds at osdl.org>

---

 drivers/net/fec.c |  240 ++++++++++++++++++++++++++++++++++++++++++++++++-----
 1 files changed, 218 insertions(+), 22 deletions(-)

applies-to: 878ed7a5d1794ff7f986b42204322e1bcf13ff7c
562d2f8ce4e463e1427ddfab5e84440323856f43
diff --git a/drivers/net/fec.c b/drivers/net/fec.c
index 85504fb..bd6983d 100644
--- a/drivers/net/fec.c
+++ b/drivers/net/fec.c
@@ -18,8 +18,8 @@
  * Much better multiple PHY support by Magnus Damm.
  * Copyright (c) 2000 Ericsson Radio Systems AB.
  *
- * Support for FEC controller of ColdFire/5270/5271/5272/5274/5275/5280/5282.
- * Copyright (c) 2001-2004 Greg Ungerer (gerg at snapgear.com)
+ * Support for FEC controller of ColdFire processors.
+ * Copyright (c) 2001-2005 Greg Ungerer (gerg at snapgear.com)
  *
  * Bug fixes and cleanup by Philippe De Muyter (phdm at macqel.be)
  * Copyright (c) 2004-2005 Macq Electronique SA.
@@ -50,7 +50,8 @@
 #include <asm/pgtable.h>
 
 #if defined(CONFIG_M523x) || defined(CONFIG_M527x) || \
-    defined(CONFIG_M5272) || defined(CONFIG_M528x)
+    defined(CONFIG_M5272) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 #include <asm/coldfire.h>
 #include <asm/mcfsim.h>
 #include "fec.h"
@@ -77,6 +78,8 @@ static unsigned int fec_hw[] = {
 	(MCF_MBAR + 0x1800),
 #elif defined(CONFIG_M523x) || defined(CONFIG_M528x)
 	(MCF_MBAR + 0x1000),
+#elif defined(CONFIG_M520x)
+	(MCF_MBAR+0x30000),
 #else
 	&(((immap_t *)IMAP_ADDR)->im_cpm.cp_fec),
 #endif
@@ -139,6 +142,10 @@ typedef struct {
 #define TX_RING_SIZE		16	/* Must be power of two */
 #define TX_RING_MOD_MASK	15	/*   for this to work */
 
+#if (((RX_RING_SIZE + TX_RING_SIZE) * 8) > PAGE_SIZE)
+#error "FEC: descriptor ring size contants too large"
+#endif
+
 /* Interrupt events/masks.
 */
 #define FEC_ENET_HBERR	((uint)0x80000000)	/* Heartbeat error */
@@ -164,7 +171,8 @@ typedef struct {
  * size bits. Other FEC hardware does not, so we need to take that into
  * account when setting it.
  */
-#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x)
+#if defined(CONFIG_M523x) || defined(CONFIG_M527x) || defined(CONFIG_M528x) || \
+    defined(CONFIG_M520x)
 #define	OPT_FRAME_SIZE	(PKT_MAXBUF_SIZE << 16)
 #else
 #define	OPT_FRAME_SIZE	0
@@ -1137,6 +1145,65 @@ static phy_info_t const phy_info_ks8721b
 };
 
 /* ------------------------------------------------------------------------- */
+/* register definitions for the DP83848 */
+
+#define MII_DP8384X_PHYSTST    16  /* PHY Status Register */
+
+static void mii_parse_dp8384x_sr2(uint mii_reg, struct net_device *dev)
+{
+	struct fec_enet_private *fep = dev->priv;
+	volatile uint *s = &(fep->phy_status);
+
+	*s &= ~(PHY_STAT_SPMASK | PHY_STAT_LINK | PHY_STAT_ANC);
+
+	/* Link up */
+	if (mii_reg & 0x0001) {
+		fep->link = 1;
+		*s |= PHY_STAT_LINK;
+	} else
+		fep->link = 0;
+	/* Status of link */
+	if (mii_reg & 0x0010)   /* Autonegotioation complete */
+		*s |= PHY_STAT_ANC;
+	if (mii_reg & 0x0002) {   /* 10MBps? */
+		if (mii_reg & 0x0004)   /* Full Duplex? */
+			*s |= PHY_STAT_10FDX;
+		else
+			*s |= PHY_STAT_10HDX;
+	} else {                  /* 100 Mbps? */
+		if (mii_reg & 0x0004)   /* Full Duplex? */
+			*s |= PHY_STAT_100FDX;
+		else
+			*s |= PHY_STAT_100HDX;
+	}
+	if (mii_reg & 0x0008)
+		*s |= PHY_STAT_FAULT;
+}
+
+static phy_info_t phy_info_dp83848= {
+	0x020005c9,
+	"DP83848",
+
+	(const phy_cmd_t []) {  /* config */
+		{ mk_mii_read(MII_REG_CR), mii_parse_cr },
+		{ mk_mii_read(MII_REG_ANAR), mii_parse_anar },
+		{ mk_mii_read(MII_DP8384X_PHYSTST), mii_parse_dp8384x_sr2 },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* startup - enable interrupts */
+		{ mk_mii_write(MII_REG_CR, 0x1200), NULL }, /* autonegotiate */
+		{ mk_mii_read(MII_REG_SR), mii_parse_sr },
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) { /* ack_int - never happens, no interrupt */
+		{ mk_mii_end, }
+	},
+	(const phy_cmd_t []) {  /* shutdown */
+		{ mk_mii_end, }
+	},
+};
+
+/* ------------------------------------------------------------------------- */
 
 static phy_info_t const * const phy_info[] = {
 	&phy_info_lxt970,
@@ -1144,6 +1211,7 @@ static phy_info_t const * const phy_info
 	&phy_info_qs6612,
 	&phy_info_am79c874,
 	&phy_info_ks8721bl,
+	&phy_info_dp83848,
 	NULL
 };
 
@@ -1422,6 +1490,134 @@ static void __inline__ fec_uncache(unsig
 
 /* ------------------------------------------------------------------------- */
 
+#elif defined(CONFIG_M520x)
+
+/*
+ *	Code specific to Coldfire 520x
+ */
+static void __inline__ fec_request_intrs(struct net_device *dev)
+{
+	struct fec_enet_private *fep;
+	int b;
+	static const struct idesc {
+		char *name;
+		unsigned short irq;
+	} *idp, id[] = {
+		{ "fec(TXF)", 23 },
+		{ "fec(TXB)", 24 },
+		{ "fec(TXFIFO)", 25 },
+		{ "fec(TXCR)", 26 },
+		{ "fec(RXF)", 27 },
+		{ "fec(RXB)", 28 },
+		{ "fec(MII)", 29 },
+		{ "fec(LC)", 30 },
+		{ "fec(HBERR)", 31 },
+		{ "fec(GRA)", 32 },
+		{ "fec(EBERR)", 33 },
+		{ "fec(BABT)", 34 },
+		{ "fec(BABR)", 35 },
+		{ NULL },
+	};
+
+	fep = netdev_priv(dev);
+	b = 64 + 13;
+
+	/* Setup interrupt handlers. */
+	for (idp = id; idp->name; idp++) {
+		if (request_irq(b+idp->irq,fec_enet_interrupt,0,idp->name,dev)!=0)
+			printk("FEC: Could not allocate %s IRQ(%d)!\n", idp->name, b+idp->irq);
+	}
+
+	/* Unmask interrupts at ColdFire interrupt controller */
+	{
+		volatile unsigned char  *icrp;
+		volatile unsigned long  *imrp;
+
+		icrp = (volatile unsigned char *) (MCF_IPSBAR + MCFICM_INTC0 +
+			MCFINTC_ICR0);
+		for (b = 36; (b < 49); b++)
+			icrp[b] = 0x04;
+		imrp = (volatile unsigned long *) (MCF_IPSBAR + MCFICM_INTC0 +
+			MCFINTC_IMRH);
+		*imrp &= ~0x0001FFF0;
+	}
+	*(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FEC) |= 0xf0;
+	*(volatile unsigned char *)(MCF_IPSBAR + MCF_GPIO_PAR_FECI2C) |= 0x0f;
+}
+
+static void __inline__ fec_set_mii(struct net_device *dev, struct fec_enet_private *fep)
+{
+	volatile fec_t *fecp;
+
+	fecp = fep->hwp;
+	fecp->fec_r_cntrl = OPT_FRAME_SIZE | 0x04;
+	fecp->fec_x_cntrl = 0x00;
+
+	/*
+	 * Set MII speed to 2.5 MHz
+	 * See 5282 manual section 17.5.4.7: MSCR
+	 */
+	fep->phy_speed = ((((MCF_CLK / 2) / (2500000 / 10)) + 5) / 10) * 2;
+	fecp->fec_mii_speed = fep->phy_speed;
+
+	fec_restart(dev, 0);
+}
+
+static void __inline__ fec_get_mac(struct net_device *dev)
+{
+	struct fec_enet_private *fep = netdev_priv(dev);
+	volatile fec_t *fecp;
+	unsigned char *iap, tmpaddr[ETH_ALEN];
+
+	fecp = fep->hwp;
+
+	if (FEC_FLASHMAC) {
+		/*
+		 * Get MAC address from FLASH.
+		 * If it is all 1's or 0's, use the default.
+		 */
+		iap = FEC_FLASHMAC;
+		if ((iap[0] == 0) && (iap[1] == 0) && (iap[2] == 0) &&
+		   (iap[3] == 0) && (iap[4] == 0) && (iap[5] == 0))
+			iap = fec_mac_default;
+		if ((iap[0] == 0xff) && (iap[1] == 0xff) && (iap[2] == 0xff) &&
+		   (iap[3] == 0xff) && (iap[4] == 0xff) && (iap[5] == 0xff))
+			iap = fec_mac_default;
+	} else {
+		*((unsigned long *) &tmpaddr[0]) = fecp->fec_addr_low;
+		*((unsigned short *) &tmpaddr[4]) = (fecp->fec_addr_high >> 16);
+		iap = &tmpaddr[0];
+	}
+
+	memcpy(dev->dev_addr, iap, ETH_ALEN);
+
+	/* Adjust MAC if using default MAC address */
+	if (iap == fec_mac_default)
+		dev->dev_addr[ETH_ALEN-1] = fec_mac_default[ETH_ALEN-1] + fep->index;
+}
+
+static void __inline__ fec_enable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_disable_phy_intr(void)
+{
+}
+
+static void __inline__ fec_phy_ack_intr(void)
+{
+}
+
+static void __inline__ fec_localhw_setup(void)
+{
+}
+
+static void __inline__ fec_uncache(unsigned long addr)
+{
+}
+
+/* ------------------------------------------------------------------------- */
+
 #else
 
 /*
@@ -1952,6 +2148,14 @@ int __init fec_enet_init(struct net_devi
 	if (index >= FEC_MAX_PORTS)
 		return -ENXIO;
 
+	/* Allocate memory for buffer descriptors.
+	*/
+	mem_addr = __get_free_page(GFP_KERNEL);
+	if (mem_addr == 0) {
+		printk("FEC: allocate descriptor memory failed?\n");
+		return -ENOMEM;
+	}
+
 	/* Create an Ethernet device instance.
 	*/
 	fecp = (volatile fec_t *) fec_hw[index];
@@ -1964,16 +2168,6 @@ int __init fec_enet_init(struct net_devi
 	fecp->fec_ecntrl = 1;
 	udelay(10);
 
-	/* Clear and enable interrupts */
-	fecp->fec_ievent = 0xffc00000;
-	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
-		FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
-	fecp->fec_hash_table_high = 0;
-	fecp->fec_hash_table_low = 0;
-	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
-        fecp->fec_ecntrl = 2;
-        fecp->fec_r_des_active = 0x01000000;
-
 	/* Set the Ethernet address.  If using multiple Enets on the 8xx,
 	 * this needs some work to get unique addresses.
 	 *
@@ -1982,14 +2176,6 @@ int __init fec_enet_init(struct net_devi
 	 */
 	fec_get_mac(dev);
 
-	/* Allocate memory for buffer descriptors.
-	*/
-	if (((RX_RING_SIZE + TX_RING_SIZE) * sizeof(cbd_t)) > PAGE_SIZE) {
-		printk("FEC init error.  Need more space.\n");
-		printk("FEC initialization failed.\n");
-		return 1;
-	}
-	mem_addr = __get_free_page(GFP_KERNEL);
 	cbd_base = (cbd_t *)mem_addr;
 	/* XXX: missing check for allocation failure */
 
@@ -2067,6 +2253,16 @@ int __init fec_enet_init(struct net_devi
 	*/
 	fec_request_intrs(dev);
 
+	/* Clear and enable interrupts */
+	fecp->fec_ievent = 0xffc00000;
+	fecp->fec_imask = (FEC_ENET_TXF | FEC_ENET_TXB |
+		FEC_ENET_RXF | FEC_ENET_RXB | FEC_ENET_MII);
+	fecp->fec_hash_table_high = 0;
+	fecp->fec_hash_table_low = 0;
+	fecp->fec_r_buff_size = PKT_MAXBLR_SIZE;
+	fecp->fec_ecntrl = 2;
+	fecp->fec_r_des_active = 0x01000000;
+
 	dev->base_addr = (unsigned long)fecp;
 
 	/* The FEC Ethernet specific entries in the device structure. */
---
0.99.8.GIT


--- NEW FILE 2910-Ran-scripts-Lindent-on-drivers-net-wireless-ipw2-1-2-00.-c-h.txt ---
Subject: [PATCH] Ran scripts/Lindent on drivers/net/wireless/ipw2{1,2}00.{c,h}
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1126709249 -0500

No other changes.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2100.c | 2219 ++++++++++++++++++++--------------------
 drivers/net/wireless/ipw2100.h |  158 +--
 2 files changed, 1157 insertions(+), 1220 deletions(-)

applies-to: 3d5b65e5cb1f8549c9de343b986c5b4390125563
ee8e365aa6395e721399127ccf3d28d269136f0e
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index ad7f8cd..a15eef1 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -174,10 +174,9 @@ that only one external action is invoked
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2100 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2004 Intel Corporation"
 
-
 /* Debugging stuff */
 #ifdef CONFIG_IPW_DEBUG
-#define CONFIG_IPW2100_RX_DEBUG   /* Reception debugging */
+#define CONFIG_IPW2100_RX_DEBUG	/* Reception debugging */
 #endif
 
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
@@ -220,18 +219,18 @@ do { \
 } while (0)
 #else
 #define IPW_DEBUG(level, message...) do {} while (0)
-#endif /* CONFIG_IPW_DEBUG */
+#endif				/* CONFIG_IPW_DEBUG */
 
 #ifdef CONFIG_IPW_DEBUG
 static const char *command_types[] = {
 	"undefined",
-	"unused", /* HOST_ATTENTION */
+	"unused",		/* HOST_ATTENTION */
 	"HOST_COMPLETE",
-	"unused", /* SLEEP */
-	"unused", /* HOST_POWER_DOWN */
+	"unused",		/* SLEEP */
+	"unused",		/* HOST_POWER_DOWN */
 	"unused",
 	"SYSTEM_CONFIG",
-	"unused", /* SET_IMR */
+	"unused",		/* SET_IMR */
 	"SSID",
 	"MANDATORY_BSSID",
 	"AUTHENTICATION_TYPE",
@@ -277,17 +276,16 @@ static const char *command_types[] = {
 	"GROUP_ORDINALS",
 	"SHORT_RETRY_LIMIT",
 	"LONG_RETRY_LIMIT",
-	"unused", /* SAVE_CALIBRATION */
-	"unused", /* RESTORE_CALIBRATION */
+	"unused",		/* SAVE_CALIBRATION */
+	"unused",		/* RESTORE_CALIBRATION */
 	"undefined",
 	"undefined",
 	"undefined",
 	"HOST_PRE_POWER_DOWN",
-	"unused", /* HOST_INTERRUPT_COALESCING */
+	"unused",		/* HOST_INTERRUPT_COALESCING */
 	"undefined",
 	"CARD_DISABLE_PHY_OFF",
-	"MSDU_TX_RATES"
-	"undefined",
+	"MSDU_TX_RATES" "undefined",
 	"undefined",
 	"SET_STATION_STAT_BITS",
 	"CLEAR_STATIONS_STAT_BITS",
@@ -298,7 +296,6 @@ static const char *command_types[] = {
 };
 #endif
 
-
 /* Pre-decl until we get the code solid and then we can clean it up */
 static void ipw2100_tx_send_commands(struct ipw2100_priv *priv);
 static void ipw2100_tx_send_data(struct ipw2100_priv *priv);
@@ -321,11 +318,10 @@ static void ipw2100_release_firmware(str
 static int ipw2100_ucode_download(struct ipw2100_priv *priv,
 				  struct ipw2100_fw *fw);
 static void ipw2100_wx_event_work(struct ipw2100_priv *priv);
-static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device * dev);
+static struct iw_statistics *ipw2100_wx_wireless_stats(struct net_device *dev);
 static struct iw_handler_def ipw2100_wx_handler_def;
 
-
-static inline void read_register(struct net_device *dev, u32 reg, u32 *val)
+static inline void read_register(struct net_device *dev, u32 reg, u32 * val)
 {
 	*val = readl((void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("r: 0x%08X => 0x%08X\n", reg, *val);
@@ -337,13 +333,14 @@ static inline void write_register(struct
 	IPW_DEBUG_IO("w: 0x%08X <= 0x%08X\n", reg, val);
 }
 
-static inline void read_register_word(struct net_device *dev, u32 reg, u16 *val)
+static inline void read_register_word(struct net_device *dev, u32 reg,
+				      u16 * val)
 {
 	*val = readw((void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("r: 0x%08X => %04X\n", reg, *val);
 }
 
-static inline void read_register_byte(struct net_device *dev, u32 reg, u8 *val)
+static inline void read_register_byte(struct net_device *dev, u32 reg, u8 * val)
 {
 	*val = readb((void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("r: 0x%08X => %02X\n", reg, *val);
@@ -355,14 +352,13 @@ static inline void write_register_word(s
 	IPW_DEBUG_IO("w: 0x%08X <= %04X\n", reg, val);
 }
 
-
 static inline void write_register_byte(struct net_device *dev, u32 reg, u8 val)
 {
 	writeb(val, (void __iomem *)(dev->base_addr + reg));
 	IPW_DEBUG_IO("w: 0x%08X =< %02X\n", reg, val);
 }
 
-static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 *val)
+static inline void read_nic_dword(struct net_device *dev, u32 addr, u32 * val)
 {
 	write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
 		       addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -376,7 +372,7 @@ static inline void write_nic_dword(struc
 	write_register(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
 }
 
-static inline void read_nic_word(struct net_device *dev, u32 addr, u16 *val)
+static inline void read_nic_word(struct net_device *dev, u32 addr, u16 * val)
 {
 	write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
 		       addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -390,7 +386,7 @@ static inline void write_nic_word(struct
 	write_register_word(dev, IPW_REG_INDIRECT_ACCESS_DATA, val);
 }
 
-static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 *val)
+static inline void read_nic_byte(struct net_device *dev, u32 addr, u8 * val)
 {
 	write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
 		       addr & IPW_REG_INDIRECT_ADDR_MASK);
@@ -416,7 +412,7 @@ static inline void write_nic_dword_auto_
 }
 
 static inline void write_nic_memory(struct net_device *dev, u32 addr, u32 len,
-				    const u8 *buf)
+				    const u8 * buf)
 {
 	u32 aligned_addr;
 	u32 aligned_len;
@@ -431,32 +427,30 @@ static inline void write_nic_memory(stru
 		write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS,
 			       aligned_addr);
 		for (i = dif_len; i < 4; i++, buf++)
-			write_register_byte(
-				dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
-				*buf);
+			write_register_byte(dev,
+					    IPW_REG_INDIRECT_ACCESS_DATA + i,
+					    *buf);
 
 		len -= dif_len;
 		aligned_addr += 4;
 	}
 
 	/* read DWs through autoincrement registers */
-	write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS,
-		       aligned_addr);
+	write_register(dev, IPW_REG_AUTOINCREMENT_ADDRESS, aligned_addr);
 	aligned_len = len & (~0x3);
 	for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
-		write_register(
-			dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *)buf);
+		write_register(dev, IPW_REG_AUTOINCREMENT_DATA, *(u32 *) buf);
 
 	/* copy the last nibble */
 	dif_len = len - aligned_len;
 	write_register(dev, IPW_REG_INDIRECT_ACCESS_ADDRESS, aligned_addr);
 	for (i = 0; i < dif_len; i++, buf++)
-		write_register_byte(
-			dev, IPW_REG_INDIRECT_ACCESS_DATA + i, *buf);
+		write_register_byte(dev, IPW_REG_INDIRECT_ACCESS_DATA + i,
+				    *buf);
 }
 
 static inline void read_nic_memory(struct net_device *dev, u32 addr, u32 len,
-				   u8 *buf)
+				   u8 * buf)
 {
[...5073 lines suppressed...]
-
 /* system configuration bit mask: */
 #define IPW_CFG_MONITOR               0x00004
 #define IPW_CFG_PREAMBLE_AUTO        0x00010
@@ -704,7 +693,7 @@ struct ipw2100_priv {
 #define IPW2100_INTA_TX_TRANSFER               (0x00000001)	// Bit 0 (LSB)
 #define IPW2100_INTA_RX_TRANSFER               (0x00000002)	// Bit 1
 #define IPW2100_INTA_TX_COMPLETE	       (0x00000004)	// Bit 2
-#define IPW2100_INTA_EVENT_INTERRUPT           (0x00000008)     // Bit 3
+#define IPW2100_INTA_EVENT_INTERRUPT           (0x00000008)	// Bit 3
 #define IPW2100_INTA_STATUS_CHANGE             (0x00000010)	// Bit 4
 #define IPW2100_INTA_BEACON_PERIOD_EXPIRED     (0x00000020)	// Bit 5
 #define IPW2100_INTA_SLAVE_MODE_HOST_COMMAND_DONE  (0x00010000)	// Bit 16
@@ -784,9 +773,6 @@ struct ipw2100_priv {
 #define IPW_CARD_DISABLE_PHY_OFF_COMPLETE_WAIT	    100	// 100 milli
 #define IPW_PREPARE_POWER_DOWN_COMPLETE_WAIT	    100	// 100 milli
 
-
-
-
 #define IPW_HEADER_802_11_SIZE		 sizeof(struct ieee80211_hdr_3addr)
 #define IPW_MAX_80211_PAYLOAD_SIZE              2304U
 #define IPW_MAX_802_11_PAYLOAD_LENGTH		2312
@@ -843,8 +829,8 @@ struct ipw2100_rx {
 #define IPW_TX_POWER_MIN_DBM         (-12)
 #define IPW_TX_POWER_MAX_DBM         16
 
-#define FW_SCAN_DONOT_ASSOCIATE     0x0001 // Dont Attempt to Associate after Scan
-#define FW_SCAN_PASSIVE             0x0008 // Force PASSSIVE Scan
+#define FW_SCAN_DONOT_ASSOCIATE     0x0001	// Dont Attempt to Associate after Scan
+#define FW_SCAN_PASSIVE             0x0008	// Force PASSSIVE Scan
 
 #define REG_MIN_CHANNEL             0
 #define REG_MAX_CHANNEL             14
@@ -856,7 +842,6 @@ struct ipw2100_rx {
 #define DIVERSITY_ANTENNA_A         1	// Use antenna A
 #define DIVERSITY_ANTENNA_B         2	// Use antenna B
 
-
 #define HOST_COMMAND_WAIT 0
 #define HOST_COMMAND_NO_WAIT 1
 
@@ -873,7 +858,6 @@ struct ipw2100_rx {
 #define TYPE_ASSOCIATION_REQUEST	0x0013
 #define TYPE_REASSOCIATION_REQUEST	0x0014
 
-
 #define HW_FEATURE_RFKILL (0x0001)
 #define RF_KILLSWITCH_OFF (1)
 #define RF_KILLSWITCH_ON  (0)
@@ -895,7 +879,7 @@ struct ipw2100_rx {
 // Fixed size data: Ordinal Table 1
 typedef enum _ORDINAL_TABLE_1 {	// NS - means Not Supported by FW
 // Transmit statistics
-	IPW_ORD_STAT_TX_HOST_REQUESTS = 1,// # of requested Host Tx's (MSDU)
+	IPW_ORD_STAT_TX_HOST_REQUESTS = 1,	// # of requested Host Tx's (MSDU)
 	IPW_ORD_STAT_TX_HOST_COMPLETE,	// # of successful Host Tx's (MSDU)
 	IPW_ORD_STAT_TX_DIR_DATA,	// # of successful Directed Tx's (MSDU)
 
@@ -905,42 +889,42 @@ typedef enum _ORDINAL_TABLE_1 {	// NS - 
 	IPW_ORD_STAT_TX_DIR_DATA11,	// # of successful Directed Tx's (MSDU) @ 11MB
 	IPW_ORD_STAT_TX_DIR_DATA22,	// # of successful Directed Tx's (MSDU) @ 22MB
 
-	IPW_ORD_STAT_TX_NODIR_DATA1 = 13,// # of successful Non_Directed Tx's (MSDU) @ 1MB
+	IPW_ORD_STAT_TX_NODIR_DATA1 = 13,	// # of successful Non_Directed Tx's (MSDU) @ 1MB
 	IPW_ORD_STAT_TX_NODIR_DATA2,	// # of successful Non_Directed Tx's (MSDU) @ 2MB
 	IPW_ORD_STAT_TX_NODIR_DATA5_5,	// # of successful Non_Directed Tx's (MSDU) @ 5.5MB
 	IPW_ORD_STAT_TX_NODIR_DATA11,	// # of successful Non_Directed Tx's (MSDU) @ 11MB
 
 	IPW_ORD_STAT_NULL_DATA = 21,	// # of successful NULL data Tx's
-	IPW_ORD_STAT_TX_RTS,	        // # of successful Tx RTS
-	IPW_ORD_STAT_TX_CTS,	        // # of successful Tx CTS
-	IPW_ORD_STAT_TX_ACK,	        // # of successful Tx ACK
-	IPW_ORD_STAT_TX_ASSN,	        // # of successful Association Tx's
+	IPW_ORD_STAT_TX_RTS,	// # of successful Tx RTS
+	IPW_ORD_STAT_TX_CTS,	// # of successful Tx CTS
+	IPW_ORD_STAT_TX_ACK,	// # of successful Tx ACK
+	IPW_ORD_STAT_TX_ASSN,	// # of successful Association Tx's
 	IPW_ORD_STAT_TX_ASSN_RESP,	// # of successful Association response Tx's
-	IPW_ORD_STAT_TX_REASSN,	        // # of successful Reassociation Tx's
+	IPW_ORD_STAT_TX_REASSN,	// # of successful Reassociation Tx's
 	IPW_ORD_STAT_TX_REASSN_RESP,	// # of successful Reassociation response Tx's
-	IPW_ORD_STAT_TX_PROBE,	        // # of probes successfully transmitted
+	IPW_ORD_STAT_TX_PROBE,	// # of probes successfully transmitted
 	IPW_ORD_STAT_TX_PROBE_RESP,	// # of probe responses successfully transmitted
-	IPW_ORD_STAT_TX_BEACON,	        // # of tx beacon
-	IPW_ORD_STAT_TX_ATIM,	        // # of Tx ATIM
+	IPW_ORD_STAT_TX_BEACON,	// # of tx beacon
+	IPW_ORD_STAT_TX_ATIM,	// # of Tx ATIM
 	IPW_ORD_STAT_TX_DISASSN,	// # of successful Disassociation TX
-	IPW_ORD_STAT_TX_AUTH,	        // # of successful Authentication Tx
-	IPW_ORD_STAT_TX_DEAUTH,	        // # of successful Deauthentication TX
+	IPW_ORD_STAT_TX_AUTH,	// # of successful Authentication Tx
+	IPW_ORD_STAT_TX_DEAUTH,	// # of successful Deauthentication TX
 
-	IPW_ORD_STAT_TX_TOTAL_BYTES = 41,// Total successful Tx data bytes
-	IPW_ORD_STAT_TX_RETRIES,         // # of Tx retries
-	IPW_ORD_STAT_TX_RETRY1,          // # of Tx retries at 1MBPS
-	IPW_ORD_STAT_TX_RETRY2,          // # of Tx retries at 2MBPS
-	IPW_ORD_STAT_TX_RETRY5_5,	 // # of Tx retries at 5.5MBPS
-	IPW_ORD_STAT_TX_RETRY11,	 // # of Tx retries at 11MBPS
+	IPW_ORD_STAT_TX_TOTAL_BYTES = 41,	// Total successful Tx data bytes
+	IPW_ORD_STAT_TX_RETRIES,	// # of Tx retries
+	IPW_ORD_STAT_TX_RETRY1,	// # of Tx retries at 1MBPS
+	IPW_ORD_STAT_TX_RETRY2,	// # of Tx retries at 2MBPS
+	IPW_ORD_STAT_TX_RETRY5_5,	// # of Tx retries at 5.5MBPS
+	IPW_ORD_STAT_TX_RETRY11,	// # of Tx retries at 11MBPS
 
 	IPW_ORD_STAT_TX_FAILURES = 51,	// # of Tx Failures
 	IPW_ORD_STAT_TX_ABORT_AT_HOP,	//NS // # of Tx's aborted at hop time
-	IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,// # of times max tries in a hop failed
+	IPW_ORD_STAT_TX_MAX_TRIES_IN_HOP,	// # of times max tries in a hop failed
 	IPW_ORD_STAT_TX_ABORT_LATE_DMA,	//NS // # of times tx aborted due to late dma setup
 	IPW_ORD_STAT_TX_ABORT_STX,	//NS // # of times backoff aborted
 	IPW_ORD_STAT_TX_DISASSN_FAIL,	// # of times disassociation failed
-	IPW_ORD_STAT_TX_ERR_CTS,         // # of missed/bad CTS frames
-	IPW_ORD_STAT_TX_BPDU,	        //NS // # of spanning tree BPDUs sent
+	IPW_ORD_STAT_TX_ERR_CTS,	// # of missed/bad CTS frames
+	IPW_ORD_STAT_TX_BPDU,	//NS // # of spanning tree BPDUs sent
 	IPW_ORD_STAT_TX_ERR_ACK,	// # of tx err due to acks
 
 	// Receive statistics
@@ -952,7 +936,7 @@ typedef enum _ORDINAL_TABLE_1 {	// NS - 
 	IPW_ORD_STAT_RX_DIR_DATA11,	// # of directed packets at 11MB
 	IPW_ORD_STAT_RX_DIR_DATA22,	// # of directed packets at 22MB
 
-	IPW_ORD_STAT_RX_NODIR_DATA = 71,// # of nondirected packets
+	IPW_ORD_STAT_RX_NODIR_DATA = 71,	// # of nondirected packets
 	IPW_ORD_STAT_RX_NODIR_DATA1,	// # of nondirected packets at 1MB
 	IPW_ORD_STAT_RX_NODIR_DATA2,	// # of nondirected packets at 2MB
 	IPW_ORD_STAT_RX_NODIR_DATA5_5,	// # of nondirected packets at 5.5MB
@@ -977,18 +961,18 @@ typedef enum _ORDINAL_TABLE_1 {	// NS - 
 	IPW_ORD_STAT_RX_AUTH,	// # of authentication Rx
 	IPW_ORD_STAT_RX_DEAUTH,	// # of deauthentication Rx
 
-	IPW_ORD_STAT_RX_TOTAL_BYTES = 101,// Total rx data bytes received
-	IPW_ORD_STAT_RX_ERR_CRC,	 // # of packets with Rx CRC error
-	IPW_ORD_STAT_RX_ERR_CRC1,	 // # of Rx CRC errors at 1MB
-	IPW_ORD_STAT_RX_ERR_CRC2,	 // # of Rx CRC errors at 2MB
-	IPW_ORD_STAT_RX_ERR_CRC5_5,	 // # of Rx CRC errors at 5.5MB
-	IPW_ORD_STAT_RX_ERR_CRC11,	 // # of Rx CRC errors at 11MB
-
-	IPW_ORD_STAT_RX_DUPLICATE1 = 112, // # of duplicate rx packets at 1MB
-	IPW_ORD_STAT_RX_DUPLICATE2,	 // # of duplicate rx packets at 2MB
-	IPW_ORD_STAT_RX_DUPLICATE5_5,	 // # of duplicate rx packets at 5.5MB
-	IPW_ORD_STAT_RX_DUPLICATE11,	 // # of duplicate rx packets at 11MB
-	IPW_ORD_STAT_RX_DUPLICATE = 119, // # of duplicate rx packets
+	IPW_ORD_STAT_RX_TOTAL_BYTES = 101,	// Total rx data bytes received
+	IPW_ORD_STAT_RX_ERR_CRC,	// # of packets with Rx CRC error
+	IPW_ORD_STAT_RX_ERR_CRC1,	// # of Rx CRC errors at 1MB
+	IPW_ORD_STAT_RX_ERR_CRC2,	// # of Rx CRC errors at 2MB
+	IPW_ORD_STAT_RX_ERR_CRC5_5,	// # of Rx CRC errors at 5.5MB
+	IPW_ORD_STAT_RX_ERR_CRC11,	// # of Rx CRC errors at 11MB
+
+	IPW_ORD_STAT_RX_DUPLICATE1 = 112,	// # of duplicate rx packets at 1MB
+	IPW_ORD_STAT_RX_DUPLICATE2,	// # of duplicate rx packets at 2MB
+	IPW_ORD_STAT_RX_DUPLICATE5_5,	// # of duplicate rx packets at 5.5MB
+	IPW_ORD_STAT_RX_DUPLICATE11,	// # of duplicate rx packets at 11MB
+	IPW_ORD_STAT_RX_DUPLICATE = 119,	// # of duplicate rx packets
 
 	IPW_ORD_PERS_DB_LOCK = 120,	// # locking fw permanent  db
 	IPW_ORD_PERS_DB_SIZE,	// # size of fw permanent  db
@@ -1006,17 +990,17 @@ typedef enum _ORDINAL_TABLE_1 {	// NS - 
 	IPW_ORD_STAT_RX_ICV_ERRORS,	// # of ICV errors during decryption
 
 // PSP Statistics
-	IPW_ORD_STAT_PSP_SUSPENSION = 137,// # of times adapter suspended
+	IPW_ORD_STAT_PSP_SUSPENSION = 137,	// # of times adapter suspended
 	IPW_ORD_STAT_PSP_BCN_TIMEOUT,	// # of beacon timeout
 	IPW_ORD_STAT_PSP_POLL_TIMEOUT,	// # of poll response timeouts
-	IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,// # of timeouts waiting for last broadcast/muticast pkt
+	IPW_ORD_STAT_PSP_NONDIR_TIMEOUT,	// # of timeouts waiting for last broadcast/muticast pkt
 	IPW_ORD_STAT_PSP_RX_DTIMS,	// # of PSP DTIMs received
 	IPW_ORD_STAT_PSP_RX_TIMS,	// # of PSP TIMs received
 	IPW_ORD_STAT_PSP_STATION_ID,	// PSP Station ID
 
 // Association and roaming
 	IPW_ORD_LAST_ASSN_TIME = 147,	// RTC time of last association
-	IPW_ORD_STAT_PERCENT_MISSED_BCNS,// current calculation of % missed beacons
+	IPW_ORD_STAT_PERCENT_MISSED_BCNS,	// current calculation of % missed beacons
 	IPW_ORD_STAT_PERCENT_RETRIES,	// current calculation of % missed tx retries
 	IPW_ORD_ASSOCIATED_AP_PTR,	// If associated, this is ptr to the associated
 	// AP table entry. set to 0 if not associated
@@ -1151,7 +1135,7 @@ struct ipw2100_fw_chunk {
 };
 
 struct ipw2100_fw_chunk_set {
-   	const void *data;
+	const void *data;
 	unsigned long size;
 };
 
@@ -1164,4 +1148,4 @@ struct ipw2100_fw {
 
 #define MAX_FW_VERSION_LEN 14
 
-#endif /* _IPW2100_H */
+#endif				/* _IPW2100_H */
---
0.99.8.GIT


--- NEW FILE 2911-IPW_DEBUG-has-already-included-DRV_NAME-remove-double-prefix-print.txt ---
Subject: [PATCH] IPW_DEBUG has already included DRV_NAME, remove double prefix print.
From: Zhu Yi <chuyee at debian.sh.intel.com>
Date: 1120457160 +0800

---

 drivers/net/wireless/ipw2100.c |   16 +++++++---------
 1 files changed, 7 insertions(+), 9 deletions(-)

applies-to: f069489a0d07c643bdc9caf12cfd7a9cfcadfbf1
a1e695adca76f5729224242e4f2f9f6ceb6863d1
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index a15eef1..449c1c0 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -1833,7 +1833,7 @@ static void ipw2100_down(struct ipw2100_
 
 #ifdef ACPI_CSTATE_LIMIT_DEFINED
 	if (priv->config & CFG_C3_DISABLED) {
-		IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
+		IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
 		acpi_set_cstate_limit(priv->cstate_limit);
 		priv->config &= ~CFG_C3_DISABLED;
 	}
@@ -1858,8 +1858,7 @@ static void ipw2100_reset_adapter(struct
 	int associated = priv->status & STATUS_ASSOCIATED;
 
 	spin_lock_irqsave(&priv->low_lock, flags);
-	IPW_DEBUG_INFO(DRV_NAME ": %s: Restarting adapter.\n",
-		       priv->net_dev->name);
+	IPW_DEBUG_INFO(": %s: Restarting adapter.\n", priv->net_dev->name);
 	priv->resets++;
 	priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
 	priv->status |= STATUS_SECURITY_UPDATED;
@@ -2062,7 +2061,7 @@ static void isr_indicate_rf_kill(struct 
 
 #ifdef ACPI_CSTATE_LIMIT_DEFINED
 	if (priv->config & CFG_C3_DISABLED) {
-		IPW_DEBUG_INFO(DRV_NAME ": Resetting C3 transitions.\n");
+		IPW_DEBUG_INFO(": Resetting C3 transitions.\n");
 		acpi_set_cstate_limit(priv->cstate_limit);
 		priv->config &= ~CFG_C3_DISABLED;
 	}
@@ -2300,11 +2299,11 @@ static inline void ipw2100_corruption_de
 	int limit;
 #endif
 
-	IPW_DEBUG_INFO(DRV_NAME ": PCI latency error detected at "
-		       "0x%04zX.\n", i * sizeof(struct ipw2100_status));
+	IPW_DEBUG_INFO(": PCI latency error detected at 0x%04zX.\n",
+		       i * sizeof(struct ipw2100_status));
 
 #ifdef ACPI_CSTATE_LIMIT_DEFINED
-	IPW_DEBUG_INFO(DRV_NAME ": Disabling C3 transitions.\n");
+	IPW_DEBUG_INFO(": Disabling C3 transitions.\n");
 	limit = acpi_get_cstate_limit();
 	if (limit > 2) {
 		priv->cstate_limit = limit;
@@ -4001,8 +4000,7 @@ static ssize_t store_debug_level(struct 
 	} else
 		val = simple_strtoul(p, &p, 10);
 	if (p == buf)
-		IPW_DEBUG_INFO(DRV_NAME
-			       ": %s is not in hex or decimal form.\n", buf);
+		IPW_DEBUG_INFO(": %s is not in hex or decimal form.\n", buf);
 	else
 		ipw2100_debug_level = val;
 
---
0.99.8.GIT


--- NEW FILE 2912-Catch-ipw2200-up-to-equivelancy-with-v1.0.1.txt ---
Subject: [PATCH] Catch ipw2200 up to equivelancy with v1.0.1
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124936716 -0500

This commit contains the following fixes:

Fixed #559: iwconfig rate support (thanks to Florian Hackenberger)

Improved link signal quality calculation (thanks to Bill Moss)

Fixed a problem with sensitivity threshold during association

Added iwpriv for turning forcing long preamble support:
  % iwpriv eth1 set_preamble 1|0

Fixed #542 and #377 support for short preamble

Fixed locked BSSID reporting channel number (thanks to Pedro
Ramalhais)

Fixed type-o with scan watchdog timeout message (thanks to Pedro
Ramalhais)

Changed logic for displaying get_mode output so the code is easier to
follow (thanks to Pedro Ramalhais)

Added initial support for WPA (thanks to Yi Zhu) -- tested with
wpa_supplicant (either tip w/ ipw driver, or with -Dipw2100) with
both CCMP and TKIP

Fixed problem with CCMP not working due to uninitialized 802.11
header fields (thanks to Pedro Ramalhais)

Bug references are to defects stored on http://bughost.org

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c | 1694 +++++++++++++++++++++++++++++-----------
 drivers/net/wireless/ipw2200.h |   23 -
 2 files changed, 1247 insertions(+), 470 deletions(-)

applies-to: 1a335c4a602d34d22173c77788f0d9ad00ef8310
ea2b26e0a0264650e13acac8e66d315bb818897c
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 3db0c32..ddbee3e 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -32,7 +32,7 @@
 
 #include "ipw2200.h"
 
-#define IPW2200_VERSION "1.0.0"
+#define IPW2200_VERSION "1.0.1"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2004 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
@@ -44,7 +44,6 @@ MODULE_LICENSE("GPL");
 
 static int debug = 0;
 static int channel = 0;
-static char *ifname;
 static int mode = 0;
 
 static u32 ipw_debug_level;
@@ -289,32 +288,33 @@ static void _ipw_read_indirect(struct ip
 {
 	u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
 	u32 dif_len = addr - aligned_addr;
-	u32 aligned_len;
 	u32 i;
 
 	IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
 
+	if (num <= 0) {
+		return;
+	}
+
 	/* Read the first nibble byte by byte */
 	if (unlikely(dif_len)) {
-		/* Start reading at aligned_addr + dif_len */
 		_ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
-		for (i = dif_len; i < 4; i++, buf++)
-			*buf = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
-		num -= dif_len;
+		/* Start reading at aligned_addr + dif_len */
+		for (i = dif_len; ((i < 4) && (num > 0)); i++, num--)
+			*buf++ = _ipw_read8(priv, CX2_INDIRECT_DATA + i);
 		aligned_addr += 4;
 	}
 
-	/* Read DWs through autoinc register */
 	_ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
-	aligned_len = num & CX2_INDIRECT_ADDR_MASK;
-	for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
-		*(u32 *) buf = ipw_read32(priv, CX2_AUTOINC_DATA);
+	for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
+		*(u32 *) buf = _ipw_read32(priv, CX2_AUTOINC_DATA);
 
 	/* Copy the last nibble */
-	dif_len = num - aligned_len;
-	_ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
-	for (i = 0; i < dif_len; i++, buf++)
-		*buf = ipw_read8(priv, CX2_INDIRECT_DATA + i);
+	if (unlikely(num)) {
+		_ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
+		for (i = 0; num > 0; i++, num--)
+			*buf++ = ipw_read8(priv, CX2_INDIRECT_DATA + i);
+	}
 }
 
 static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * buf,
@@ -322,32 +322,33 @@ static void _ipw_write_indirect(struct i
 {
 	u32 aligned_addr = addr & CX2_INDIRECT_ADDR_MASK;
 	u32 dif_len = addr - aligned_addr;
-	u32 aligned_len;
 	u32 i;
 
 	IPW_DEBUG_IO("addr = %i, buf = %p, num = %i\n", addr, buf, num);
 
+	if (num <= 0) {
+		return;
+	}
+
 	/* Write the first nibble byte by byte */
 	if (unlikely(dif_len)) {
-		/* Start writing at aligned_addr + dif_len */
 		_ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
-		for (i = dif_len; i < 4; i++, buf++)
+		/* Start reading at aligned_addr + dif_len */
+		for (i = dif_len; ((i < 4) && (num > 0)); i++, num--, buf++)
 			_ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
-		num -= dif_len;
 		aligned_addr += 4;
 	}
 
-	/* Write DWs through autoinc register */
 	_ipw_write32(priv, CX2_AUTOINC_ADDR, aligned_addr);
-	aligned_len = num & CX2_INDIRECT_ADDR_MASK;
-	for (i = 0; i < aligned_len; i += 4, buf += 4, aligned_addr += 4)
+	for (; num >= 4; buf += 4, aligned_addr += 4, num -= 4)
 		_ipw_write32(priv, CX2_AUTOINC_DATA, *(u32 *) buf);
 
 	/* Copy the last nibble */
-	dif_len = num - aligned_len;
-	_ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
-	for (i = 0; i < dif_len; i++, buf++)
-		_ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
+	if (unlikely(num)) {
+		_ipw_write32(priv, CX2_INDIRECT_ADDR, aligned_addr);
+		for (i = 0; num > 0; i++, num--, buf++)
+			_ipw_write8(priv, CX2_INDIRECT_DATA + i, *buf);
+	}
 }
 
 static void ipw_write_direct(struct ipw_priv *priv, u32 addr, void *buf,
@@ -945,7 +946,7 @@ static ssize_t show_rf_kill(struct devic
 static int ipw_radio_kill_sw(struct ipw_priv *priv, int disable_radio)
 {
 	if ((disable_radio ? 1 : 0) ==
-	    (priv->status & STATUS_RF_KILL_SW ? 1 : 0))
+	    ((priv->status & STATUS_RF_KILL_SW) ? 1 : 0))
 		return 0;
 
 	IPW_DEBUG_RF_KILL("Manual SW RF Kill set to: RADIO  %s\n",
@@ -987,6 +988,17 @@ static ssize_t store_rf_kill(struct devi
 
 static DEVICE_ATTR(rf_kill, S_IWUSR | S_IRUGO, show_rf_kill, store_rf_kill);
 
+static void notify_wx_assoc_event(struct ipw_priv *priv)
+{
+	union iwreq_data wrqu;
+	wrqu.ap_addr.sa_family = ARPHRD_ETHER;
+	if (priv->status & STATUS_ASSOCIATED)
+		memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
+	else
+		memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
+	wireless_send_event(priv->net_dev, SIOCGIWAP, &wrqu, NULL);
+}
+
 static void ipw_irq_tasklet(struct ipw_priv *priv)
 {
 	u32 inta, inta_mask, handled = 0;
@@ -1071,6 +1083,8 @@ static void ipw_irq_tasklet(struct ipw_p
 		wake_up_interruptible(&priv->wait_command_queue);
 		netif_carrier_off(priv->net_dev);
 		netif_stop_queue(priv->net_dev);
+		priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
+		notify_wx_assoc_event(priv);
 		cancel_delayed_work(&priv->request_scan);
 		queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
 		handled |= CX2_INTA_BIT_RF_KILL_DONE;
@@ -1162,7 +1176,7 @@ static char *get_cmd_string(u8 cmd)
 		return "UNKNOWN";
 	}
 }
-#endif				/* CONFIG_IPW_DEBUG */
[...1863 lines suppressed...]
 
 static iw_handler ipw_priv_handler[] = {
@@ -6219,19 +6976,21 @@ static iw_handler ipw_priv_handler[] = {
 	ipw_wx_get_powermode,
 	ipw_wx_set_wireless_mode,
 	ipw_wx_get_wireless_mode,
-#ifdef CONFIG_IPW_PROMISC
-	ipw_wx_set_promisc,
+	ipw_wx_set_preamble,
+	ipw_wx_get_preamble,
+#ifdef CONFIG_IPW_MONITOR
+	ipw_wx_set_monitor,
 	ipw_wx_reset,
 #endif
 };
 
 static struct iw_handler_def ipw_wx_handler_def = {
-	.standard		= ipw_wx_handlers,
-	.num_standard		= ARRAY_SIZE(ipw_wx_handlers),
-	.num_private		= ARRAY_SIZE(ipw_priv_handler),
-	.num_private_args	= ARRAY_SIZE(ipw_priv_args),
-	.private		= ipw_priv_handler,
-	.private_args		= ipw_priv_args,
+	.standard = ipw_wx_handlers,
+	.num_standard = ARRAY_SIZE(ipw_wx_handlers),
+	.num_private = ARRAY_SIZE(ipw_priv_handler),
+	.num_private_args = ARRAY_SIZE(ipw_priv_args),
+	.private = ipw_priv_handler,
+	.private_args = ipw_priv_args,
 };
 
 /*
@@ -6246,7 +7005,7 @@ static struct iw_statistics *ipw_get_wir
 
 	wstats = &priv->wstats;
 
-	/* if hw is disabled, then ipw2100_get_ordinal() can't be called.
+	/* if hw is disabled, then ipw_get_ordinal() can't be called.
 	 * ipw2100_wx_wireless_stats seems to be called before fw is
 	 * initialized.  STATUS_ASSOCIATED will only be set if the hw is up
 	 * and associated; if not associcated, the values are all meaningless
@@ -6384,8 +7143,8 @@ static inline void ipw_tx_skb(struct ipw
 	else
 		tfd->u.data.tx_flags_ext = DCT_FLAG_EXT_MODE_OFDM;
 
-	if (priv->config & CFG_PREAMBLE)
-		tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREMBL;
+	if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
+		tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
 
 	memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
 
@@ -6568,11 +7327,11 @@ static int ipw_ethtool_set_eeprom(struct
 }
 
 static struct ethtool_ops ipw_ethtool_ops = {
-	.get_link	= ipw_ethtool_get_link,
-	.get_drvinfo	= ipw_ethtool_get_drvinfo,
-	.get_eeprom_len	= ipw_ethtool_get_eeprom_len,
-	.get_eeprom	= ipw_ethtool_get_eeprom,
-	.set_eeprom	= ipw_ethtool_set_eeprom,
+	.get_link = ipw_ethtool_get_link,
+	.get_drvinfo = ipw_ethtool_get_drvinfo,
+	.get_eeprom_len = ipw_ethtool_get_eeprom_len,
+	.get_eeprom = ipw_ethtool_get_eeprom,
+	.set_eeprom = ipw_ethtool_set_eeprom,
 };
 
 static irqreturn_t ipw_isr(int irq, void *data, struct pt_regs *regs)
@@ -6918,6 +7677,25 @@ static void ipw_down(struct ipw_priv *pr
 	ipw_stop_nic(priv);
 }
 
+static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+{
+#ifdef CONFIG_IEEE80211_WPA
+	struct iwreq *wrq = (struct iwreq *)rq;
+	int ret = -1;
+	switch (cmd) {
+	case IPW_IOCTL_WPA_SUPPLICANT:
+		ret = ipw_wpa_supplicant(dev, &wrq->u.data);
+		return ret;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+
+#endif				/* CONFIG_IEEE80211_WPA */
+
+	return -EOPNOTSUPP;
+}
+
 /* Called by register_netdev() */
 static int ipw_net_init(struct net_device *dev)
 {
@@ -7065,9 +7843,6 @@ static int ipw_pci_probe(struct pci_dev 
 	}
 
 	/* Initialize module parameter values here */
-	if (ifname)
-		strncpy(net_dev->name, ifname, IFNAMSIZ);
-
 	if (associate)
 		priv->config |= CFG_ASSOCIATE;
 	else
@@ -7095,7 +7870,7 @@ static int ipw_pci_probe(struct pci_dev 
 	case 1:
 		priv->ieee->iw_mode = IW_MODE_ADHOC;
 		break;
-#ifdef CONFIG_IPW_PROMISC
+#ifdef CONFIG_IPW_MONITOR
 	case 2:
 		priv->ieee->iw_mode = IW_MODE_MONITOR;
 		break;
@@ -7164,6 +7939,7 @@ static int ipw_pci_probe(struct pci_dev 
 	net_dev->open = ipw_net_open;
 	net_dev->stop = ipw_net_stop;
 	net_dev->init = ipw_net_init;
+	net_dev->do_ioctl = ipw_ioctl;
 	net_dev->get_stats = ipw_net_get_stats;
 	net_dev->set_multicast_list = ipw_net_set_multicast_list;
 	net_dev->set_mac_address = ipw_net_set_mac_address;
@@ -7287,13 +8063,10 @@ static int ipw_pci_resume(struct pci_dev
 
 	printk(KERN_INFO "%s: Coming out of suspend...\n", dev->name);
 
-	pci_set_power_state(pdev, 0);
+	pci_set_power_state(pdev, PCI_D0);
 	pci_enable_device(pdev);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,10)
-	pci_restore_state(pdev, priv->pm_state);
-#else
 	pci_restore_state(pdev);
-#endif
+
 	/*
 	 * Suspend/Resume resets the PCI configuration space, so we have to
 	 * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
@@ -7371,10 +8144,7 @@ MODULE_PARM_DESC(debug, "debug output ma
 module_param(channel, int, 0444);
 MODULE_PARM_DESC(channel, "channel to limit associate to (default 0 [ANY])");
 
-module_param(ifname, charp, 0444);
-MODULE_PARM_DESC(ifname, "network device name (default eth%d)");
-
-#ifdef CONFIG_IPW_PROMISC
+#ifdef CONFIG_IPW_MONITOR
 module_param(mode, int, 0444);
 MODULE_PARM_DESC(mode, "network mode (0=BSS,1=IBSS,2=Monitor)");
 #else
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index e9cf32b..0680279 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -168,7 +168,8 @@ enum connection_manager_assoc_states {
 #define DCT_FLAG_CTS_REQUIRED              0x02
 
 /* use short preamble */
-#define DCT_FLAG_SHORT_PREMBL              0x04
+#define DCT_FLAG_LONG_PREAMBLE             0x00
+#define DCT_FLAG_SHORT_PREAMBLE            0x04
 
 /* RTS/CTS first */
 #define DCT_FLAG_RTS_REQD                  0x08
@@ -899,7 +900,7 @@ struct ipw_cmd {
 #define CFG_STATIC_ESSID        (1<<1)	/* Restrict assoc. to single SSID */
 #define CFG_STATIC_BSSID        (1<<2)	/* Restrict assoc. to single BSSID */
 #define CFG_CUSTOM_MAC          (1<<3)
-#define CFG_PREAMBLE            (1<<4)
+#define CFG_PREAMBLE_LONG       (1<<4)
 #define CFG_ADHOC_PERSIST       (1<<5)
 #define CFG_ASSOCIATE           (1<<6)
 #define CFG_FIXED_RATE          (1<<7)
@@ -1206,12 +1207,18 @@ do { if (ipw_debug_level & (level)) \
 /*
  * RESET Register Bit Indexes
  */
-#define CBD_RESET_REG_PRINCETON_RESET 0x00000001	/* Bit 0 (LSB) */
-#define CX2_RESET_REG_SW_RESET        0x00000080	/* Bit 7       */
-#define CX2_RESET_REG_MASTER_DISABLED 0x00000100	/* Bit 8       */
-#define CX2_RESET_REG_STOP_MASTER     0x00000200	/* Bit 9       */
-#define CX2_ARC_KESHET_CONFIG         0x08000000	/* Bit 27      */
-#define CX2_START_STANDBY             0x00000004	/* Bit 2       */
+#define CBD_RESET_REG_PRINCETON_RESET (1<<0)
+#define CX2_START_STANDBY             (1<<2)
+#define CX2_ACTIVITY_LED              (1<<4)
+#define CX2_ASSOCIATED_LED            (1<<5)
+#define CX2_OFDM_LED                  (1<<6)
+#define CX2_RESET_REG_SW_RESET        (1<<7)
+#define CX2_RESET_REG_MASTER_DISABLED (1<<8)
+#define CX2_RESET_REG_STOP_MASTER     (1<<9)
+#define CX2_GATE_ODMA                 (1<<25)
+#define CX2_GATE_IDMA                 (1<<26)
+#define CX2_ARC_KESHET_CONFIG         (1<<27)
+#define CX2_GATE_ADMA                 (1<<29)
 
 #define CX2_CSR_CIS_UPPER_BOUND	0x00000200
 #define CX2_DOMAIN_0_END 0x1000
---
0.99.8.GIT


--- NEW FILE 2913-Catch-ipw2200-up-to-equivelancy-with-v1.0.2.txt ---
Subject: [PATCH] Catch ipw2200 up to equivelancy with v1.0.2
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124937791 -0500

Removed unneeded parenthesis around numeric constant defines

Added support for iwspy

Put in fix for Ad-Hoc mode not passing through all packets (thanks to KKH)

Put in fix for fragmentation not working for fragment sizes between
441-464 bytes (thanks to Mohamed Abbas)

Fixed #592 problem of CONFIG_IEEE80211_WPA_MODULE not including WPA
support into the driver -- fixed as a result of no longer limiting WPAs
inclusion

Fixed #594 problem with user rates mask causing lack of association if
AP mandatory rate is masked out.  We now add back in as a supported rate
any mandatory rate.

Fixed #597 kernel oops due to calling dev_kfree_skb on an skb multiple times.

Added code to control LEDs that can be controlled through the wireless
NIC (vs. non-wireless HW interfaces) -- this is currently disabled by
default due to reports by some users of it hanging their laptop.

Added some more debug messages around fragmentation logic

Added locking around STATUS_HCMD_ACTIVE to prevent re-entry race
conditions

Moved ipw_adapter_restart to only execute on the priv->workqueue to
keep keyboard errors from occuring during adapter restart

Added CFG_BACKGROUND_SCAN to easily allow people to play with
background scanning implementations

Modified WPA logic to send WPA IE if one is set (vs. being based on
wpa_enabled)

Modified scan result logic to report WPA and RSN IEs if set (vs. being
based on wpa_enabled)

Fixed issues with endianess compatability between the host and
wireless adapter (thanks to York Liu and Yi Zhu)

Fixed problem with Ad-Hoc network creation causing a firmware error if
a scan was actively running (thanks to Mohamed Abbas)

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |  962 ++++++++++++++++++++++++++++++----------
 drivers/net/wireless/ipw2200.h |   73 ++-
 2 files changed, 773 insertions(+), 262 deletions(-)

applies-to: a2045d043ca6e09722d23518170900c1cc4dcc6d
a613bffd3aac89bb0a8c9b7afa72af9b0ae30f0a
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index ddbee3e..ea7a3dc 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -32,7 +32,7 @@
 
 #include "ipw2200.h"
 
-#define IPW2200_VERSION "1.0.1"
+#define IPW2200_VERSION "1.0.2"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2004 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
@@ -49,6 +49,7 @@ static int mode = 0;
 static u32 ipw_debug_level;
 static int associate = 1;
 static int auto_create = 1;
+static int led = 0;
 static int disable = 0;
 static const char ipw_modes[] = {
 	'a', 'b', 'g', '?'
@@ -637,6 +638,313 @@ static void ipw_init_ordinals(struct ipw
 
 }
 
+u32 ipw_register_toggle(u32 reg)
+{
+	reg &= ~CX2_START_STANDBY;
+	if (reg & CX2_GATE_ODMA)
+		reg &= ~CX2_GATE_ODMA;
+	if (reg & CX2_GATE_IDMA)
+		reg &= ~CX2_GATE_IDMA;
+	if (reg & CX2_GATE_ADMA)
+		reg &= ~CX2_GATE_ADMA;
+	return reg;
+}
+
+/*
+ * LED behavior:
+ * - On radio ON, turn on any LEDs that require to be on during start
+ * - On initialization, start unassociated blink
+ * - On association, disable unassociated blink
+ * - On disassociation, start unassociated blink
+ * - On radio OFF, turn off any LEDs started during radio on
+ *
+ */
+#define LD_TIME_LINK_ON 300
+#define LD_TIME_LINK_OFF 2700
+#define LD_TIME_ACT_ON 250
+
+void ipw_led_link_on(struct ipw_priv *priv)
+{
+	unsigned long flags;
+	u32 led;
+
+	/* If configured to not use LEDs, or nic_type is 1,
+	 * then we don't toggle a LINK led */
+	if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
+		return;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	if (!(priv->status & STATUS_RF_KILL_MASK) &&
+	    !(priv->status & STATUS_LED_LINK_ON)) {
+		IPW_DEBUG_LED("Link LED On\n");
+		led = ipw_read_reg32(priv, CX2_EVENT_REG);
+		led |= priv->led_association_on;
+
+		led = ipw_register_toggle(led);
+
+		IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+		ipw_write_reg32(priv, CX2_EVENT_REG, led);
+
+		priv->status |= STATUS_LED_LINK_ON;
+
+		/* If we aren't associated, schedule turning the LED off */
+		if (!(priv->status & STATUS_ASSOCIATED))
+			queue_delayed_work(priv->workqueue,
+					   &priv->led_link_off,
+					   LD_TIME_LINK_ON);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void ipw_led_link_off(struct ipw_priv *priv)
+{
+	unsigned long flags;
+	u32 led;
+
+	/* If configured not to use LEDs, or nic type is 1,
+	 * then we don't goggle the LINK led. */
+	if (priv->config & CFG_NO_LED || priv->nic_type == EEPROM_NIC_TYPE_1)
+		return;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	if (priv->status & STATUS_LED_LINK_ON) {
+		led = ipw_read_reg32(priv, CX2_EVENT_REG);
+		led &= priv->led_association_off;
+		led = ipw_register_toggle(led);
+
+		IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+		ipw_write_reg32(priv, CX2_EVENT_REG, led);
+
+		IPW_DEBUG_LED("Link LED Off\n");
+
+		priv->status &= ~STATUS_LED_LINK_ON;
+
+		/* If we aren't associated and the radio is on, schedule
+		 * turning the LED on (blink while unassociated) */
+		if (!(priv->status & STATUS_RF_KILL_MASK) &&
+		    !(priv->status & STATUS_ASSOCIATED))
+			queue_delayed_work(priv->workqueue, &priv->led_link_on,
+					   LD_TIME_LINK_OFF);
+
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void ipw_led_activity_on(struct ipw_priv *priv)
+{
+	unsigned long flags;
+	u32 led;
+
+	if (priv->config & CFG_NO_LED)
+		return;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	if (priv->status & STATUS_RF_KILL_MASK) {
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return;
+	}
+
+	if (!(priv->status & STATUS_LED_ACT_ON)) {
+		led = ipw_read_reg32(priv, CX2_EVENT_REG);
+		led |= priv->led_activity_on;
+
+		led = ipw_register_toggle(led);
+
+		IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+		ipw_write_reg32(priv, CX2_EVENT_REG, led);
+
+		IPW_DEBUG_LED("Activity LED On\n");
+
+		priv->status |= STATUS_LED_ACT_ON;
+
+		queue_delayed_work(priv->workqueue, &priv->led_act_off,
+				   LD_TIME_ACT_ON);
+	} else {
+		/* Reschedule LED off for full time period */
+		cancel_delayed_work(&priv->led_act_off);
+		queue_delayed_work(priv->workqueue, &priv->led_act_off,
+				   LD_TIME_ACT_ON);
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void ipw_led_activity_off(struct ipw_priv *priv)
+{
+	unsigned long flags;
+	u32 led;
+
+	if (priv->config & CFG_NO_LED)
+		return;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	if (priv->status & STATUS_LED_ACT_ON) {
+		led = ipw_read_reg32(priv, CX2_EVENT_REG);
+		led &= priv->led_activity_off;
+
+		led = ipw_register_toggle(led);
+
+		IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+		ipw_write_reg32(priv, CX2_EVENT_REG, led);
+
+		IPW_DEBUG_LED("Activity LED Off\n");
+
+		priv->status &= ~STATUS_LED_ACT_ON;
+	}
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void ipw_led_band_on(struct ipw_priv *priv)
+{
+	unsigned long flags;
+	u32 led;
+
+	/* Only nic type 1 supports mode LEDs */
+	if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
+		return;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	led = ipw_read_reg32(priv, CX2_EVENT_REG);
+	if (priv->assoc_network->mode == IEEE_A) {
+		led |= priv->led_ofdm_on;
+		led &= priv->led_association_off;
+		IPW_DEBUG_LED("Mode LED On: 802.11a\n");
+	} else if (priv->assoc_network->mode == IEEE_G) {
+		led |= priv->led_ofdm_on;
+		led |= priv->led_association_on;
+		IPW_DEBUG_LED("Mode LED On: 802.11g\n");
+	} else {
+		led &= priv->led_ofdm_off;
+		led |= priv->led_association_on;
+		IPW_DEBUG_LED("Mode LED On: 802.11b\n");
+	}
+
+	led = ipw_register_toggle(led);
+
+	IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+	ipw_write_reg32(priv, CX2_EVENT_REG, led);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void ipw_led_band_off(struct ipw_priv *priv)
+{
+	unsigned long flags;
+	u32 led;
+
+	/* Only nic type 1 supports mode LEDs */
+	if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
+		return;
+
+	spin_lock_irqsave(&priv->lock, flags);
+
+	led = ipw_read_reg32(priv, CX2_EVENT_REG);
+	led &= priv->led_ofdm_off;
+	led &= priv->led_association_off;
+
+	led = ipw_register_toggle(led);
+
+	IPW_DEBUG_LED("Reg: 0x%08X\n", led);
+	ipw_write_reg32(priv, CX2_EVENT_REG, led);
+
+	spin_unlock_irqrestore(&priv->lock, flags);
+}
+
+void ipw_led_radio_on(struct ipw_priv *priv)
+{
+	ipw_led_link_on(priv);
+}
+
+void ipw_led_radio_off(struct ipw_priv *priv)
+{
+	ipw_led_activity_off(priv);
+	ipw_led_link_off(priv);
+}
+
+void ipw_led_link_up(struct ipw_priv *priv)
+{
+	/* Set the Link Led on for all nic types */
+	ipw_led_link_on(priv);
+}
+
+void ipw_led_link_down(struct ipw_priv *priv)
+{
+	ipw_led_activity_off(priv);
+	ipw_led_link_off(priv);
+
+	if (priv->status & STATUS_RF_KILL_MASK)
+		ipw_led_radio_off(priv);
+}
+
+void ipw_led_init(struct ipw_priv *priv)
+{
+	priv->nic_type = priv->eeprom[EEPROM_NIC_TYPE];
+
+	/* Set the default PINs for the link and activity leds */
+	priv->led_activity_on = CX2_ACTIVITY_LED;
+	priv->led_activity_off = ~(CX2_ACTIVITY_LED);
+
+	priv->led_association_on = CX2_ASSOCIATED_LED;
+	priv->led_association_off = ~(CX2_ASSOCIATED_LED);
+
+	/* Set the default PINs for the OFDM leds */
+	priv->led_ofdm_on = CX2_OFDM_LED;
+	priv->led_ofdm_off = ~(CX2_OFDM_LED);
+
+	switch (priv->nic_type) {
+	case EEPROM_NIC_TYPE_1:
+		/* In this NIC type, the LEDs are reversed.... */
+		priv->led_activity_on = CX2_ASSOCIATED_LED;
+		priv->led_activity_off = ~(CX2_ASSOCIATED_LED);
+		priv->led_association_on = CX2_ACTIVITY_LED;
+		priv->led_association_off = ~(CX2_ACTIVITY_LED);
+
+		if (!(priv->config & CFG_NO_LED))
+			ipw_led_band_on(priv);
+
+		/* And we don't blink link LEDs for this nic, so
+		 * just return here */
+		return;
+
+	case EEPROM_NIC_TYPE_3:
+	case EEPROM_NIC_TYPE_2:
+	case EEPROM_NIC_TYPE_4:
+	case EEPROM_NIC_TYPE_0:
+		break;
+
+	default:
+		IPW_DEBUG_INFO("Unknown NIC type from EEPROM: %d\n",
+			       priv->nic_type);
+		priv->nic_type = EEPROM_NIC_TYPE_0;
+		break;
+	}
+
+	if (!(priv->config & CFG_NO_LED)) {
+		if (priv->status & STATUS_ASSOCIATED)
+			ipw_led_link_on(priv);
+		else
+			ipw_led_link_off(priv);
+	}
+}
+
+void ipw_led_shutdown(struct ipw_priv *priv)
+{
+	cancel_delayed_work(&priv->led_link_on);
+	cancel_delayed_work(&priv->led_link_off);
+	cancel_delayed_work(&priv->led_act_off);
+	ipw_led_activity_off(priv);
+	ipw_led_link_off(priv);
+	ipw_led_band_off(priv);
+}
+
 /*
  * The following adds a new attribute to the sysfs representation
  * of this device driver (i.e. a new file in /sys/bus/pci/drivers/ipw/)
@@ -648,8 +956,9 @@ static ssize_t show_debug_level(struct d
 {
 	return sprintf(buf, "0x%08X\n", ipw_debug_level);
 }
-static ssize_t store_debug_level(struct device_driver *d,
-				 const char *buf, size_t count)
+
+static ssize_t store_debug_level(struct device_driver *d, const char *buf,
+				 size_t count)
 {
 	char *p = (char *)buf;
 	u32 val;
@@ -673,6 +982,82 @@ static ssize_t store_debug_level(struct 
 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
 		   show_debug_level, store_debug_level);
 
+static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
+			     char *buf)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	return sprintf(buf, "%d\n", priv->ieee->scan_age);
+}
+
+static ssize_t store_scan_age(struct device *d, struct device_attribute *attr,
+			      const char *buf, size_t count)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	struct net_device *dev = priv->net_dev;
+	char buffer[] = "00000000";
+	unsigned long len =
+	    (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
+	unsigned long val;
+	char *p = buffer;
+
+	IPW_DEBUG_INFO("enter\n");
+
+	strncpy(buffer, buf, len);
+	buffer[len] = 0;
+
+	if (p[1] == 'x' || p[1] == 'X' || p[0] == 'x' || p[0] == 'X') {
+		p++;
+		if (p[0] == 'x' || p[0] == 'X')
+			p++;
+		val = simple_strtoul(p, &p, 16);
+	} else
+		val = simple_strtoul(p, &p, 10);
+	if (p == buffer) {
+		IPW_DEBUG_INFO("%s: user supplied invalid value.\n", dev->name);
+	} else {
+		priv->ieee->scan_age = val;
+		IPW_DEBUG_INFO("set scan_age = %u\n", priv->ieee->scan_age);
+	}
+
+	IPW_DEBUG_INFO("exit\n");
+	return len;
+}
+
+static DEVICE_ATTR(scan_age, S_IWUSR | S_IRUGO, show_scan_age, store_scan_age);
+
+static ssize_t show_led(struct device *d, struct device_attribute *attr,
+			char *buf)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	return sprintf(buf, "%d\n", (priv->config & CFG_NO_LED) ? 0 : 1);
+}
+
+static ssize_t store_led(struct device *d, struct device_attribute *attr,
+			 const char *buf, size_t count)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+
+	IPW_DEBUG_INFO("enter\n");
+
+	if (count == 0)
+		return 0;
+
+	if (*buf == 0) {
+		IPW_DEBUG_LED("Disabling LED control.\n");
+		priv->config |= CFG_NO_LED;
+		ipw_led_shutdown(priv);
+	} else {
+		IPW_DEBUG_LED("Enabling LED control.\n");
+		priv->config &= ~CFG_NO_LED;
+		ipw_led_init(priv);
+	}
+
+	IPW_DEBUG_INFO("exit\n");
+	return count;
+}
+
+static DEVICE_ATTR(led, S_IWUSR | S_IRUGO, show_led, store_led);
+
 static ssize_t show_status(struct device *d,
 			   struct device_attribute *attr, char *buf)
 {
@@ -694,23 +1079,8 @@ static DEVICE_ATTR(cfg, S_IRUGO, show_cf
 static ssize_t show_nic_type(struct device *d,
 			     struct device_attribute *attr, char *buf)
 {
-	struct ipw_priv *p = d->driver_data;
-	u8 type = p->eeprom[EEPROM_NIC_TYPE];
-
-	switch (type) {
-	case EEPROM_NIC_TYPE_STANDARD:
-		return sprintf(buf, "STANDARD\n");
-	case EEPROM_NIC_TYPE_DELL:
-		return sprintf(buf, "DELL\n");
-	case EEPROM_NIC_TYPE_FUJITSU:
-		return sprintf(buf, "FUJITSU\n");
-	case EEPROM_NIC_TYPE_IBM:
-		return sprintf(buf, "IBM\n");
-	case EEPROM_NIC_TYPE_HP:
-		return sprintf(buf, "HP\n");
-	}
-
-	return sprintf(buf, "UNKNOWN\n");
+	struct ipw_priv *priv = d->driver_data;
+	return sprintf(buf, "TYPE: %d\n", priv->nic_type);
 }
 
 static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
@@ -955,9 +1325,8 @@ static int ipw_radio_kill_sw(struct ipw_
 	if (disable_radio) {
 		priv->status |= STATUS_RF_KILL_SW;
 
-		if (priv->workqueue) {
+		if (priv->workqueue)
 			cancel_delayed_work(&priv->request_scan);
-		}
 		wake_up_interruptible(&priv->wait_command_queue);
 		queue_work(priv->workqueue, &priv->down);
 	} else {
@@ -1081,11 +1450,9 @@ static void ipw_irq_tasklet(struct ipw_p
 		IPW_DEBUG_RF_KILL("RF_KILL_DONE\n");
 		priv->status |= STATUS_RF_KILL_HW;
 		wake_up_interruptible(&priv->wait_command_queue);
-		netif_carrier_off(priv->net_dev);
-		netif_stop_queue(priv->net_dev);
 		priv->status &= ~(STATUS_ASSOCIATED | STATUS_ASSOCIATING);
-		notify_wx_assoc_event(priv);
 		cancel_delayed_work(&priv->request_scan);
+		schedule_work(&priv->link_down);
 		queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
 		handled |= CX2_INTA_BIT_RF_KILL_DONE;
 	}
@@ -1182,9 +1549,12 @@ static char *get_cmd_string(u8 cmd)
 static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
 {
 	int rc = 0;
+	unsigned long flags;
 
+	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->status & STATUS_HCMD_ACTIVE) {
 		IPW_ERROR("Already sending a command\n");
+		spin_unlock_irqrestore(&priv->lock, flags);
 		return -1;
 	}
 
@@ -1195,19 +1565,30 @@ static int ipw_send_cmd(struct ipw_priv 
 	printk_buf(IPW_DL_HOST_COMMAND, (u8 *) cmd->param, cmd->len);
 
 	rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
-	if (rc)
+	if (rc) {
+		priv->status &= ~STATUS_HCMD_ACTIVE;
+		spin_unlock_irqrestore(&priv->lock, flags);
 		return rc;
+	}
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	rc = wait_event_interruptible_timeout(priv->wait_command_queue,
 					      !(priv->
 						status & STATUS_HCMD_ACTIVE),
 					      HOST_COMPLETE_TIMEOUT);
 	if (rc == 0) {
-		IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
-			       jiffies_to_msecs(HOST_COMPLETE_TIMEOUT));
-		priv->status &= ~STATUS_HCMD_ACTIVE;
-		return -EIO;
+		spin_lock_irqsave(&priv->lock, flags);
+		if (priv->status & STATUS_HCMD_ACTIVE) {
+			IPW_DEBUG_INFO("Command completion failed out after "
+				       "%dms.\n",
+				       1000 * (HOST_COMPLETE_TIMEOUT / HZ));
+			priv->status &= ~STATUS_HCMD_ACTIVE;
+			spin_unlock_irqrestore(&priv->lock, flags);
+			return -EIO;
+		}
+		spin_unlock_irqrestore(&priv->lock, flags);
 	}
+
 	if (priv->status & STATUS_RF_KILL_MASK) {
 		IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n");
 		return -EIO;
@@ -1304,6 +1685,11 @@ static int ipw_send_adapter_address(stru
 	return 0;
 }
 
+/*
+ * NOTE: This must be executed from our workqueue as it results in udelay
+ * being called which may corrupt the keyboard if executed on default
+ * workqueue
+ */
 static void ipw_adapter_restart(void *adapter)
 {
 	struct ipw_priv *priv = adapter;
@@ -1327,7 +1713,7 @@ static void ipw_scan_check(void *data)
 		IPW_DEBUG_SCAN("Scan completion watchdog resetting "
 			       "adapter (%dms).\n",
 			       IPW_SCAN_CHECK_WATCHDOG / 100);
-		ipw_adapter_restart(priv);
+		queue_work(priv->workqueue, &priv->adapter_restart);
 	}
 }
 
@@ -1400,12 +1786,25 @@ static int ipw_send_associate(struct ipw
 		.len = sizeof(*associate)
 	};
 
+	struct ipw_associate tmp_associate;
+	memcpy(&tmp_associate, associate, sizeof(*associate));
+	tmp_associate.policy_support =
+	    cpu_to_le16(tmp_associate.policy_support);
+	tmp_associate.assoc_tsf_msw = cpu_to_le32(tmp_associate.assoc_tsf_msw);
+	tmp_associate.assoc_tsf_lsw = cpu_to_le32(tmp_associate.assoc_tsf_lsw);
+	tmp_associate.capability = cpu_to_le16(tmp_associate.capability);
+	tmp_associate.listen_interval =
+	    cpu_to_le16(tmp_associate.listen_interval);
+	tmp_associate.beacon_interval =
+	    cpu_to_le16(tmp_associate.beacon_interval);
+	tmp_associate.atim_window = cpu_to_le16(tmp_associate.atim_window);
+
 	if (!priv || !associate) {
 		IPW_ERROR("Invalid args\n");
 		return -1;
 	}
 
-	memcpy(&cmd.param, associate, sizeof(*associate));
+	memcpy(&cmd.param, &tmp_associate, sizeof(*associate));
 	if (ipw_send_cmd(priv, &cmd)) {
 		IPW_ERROR("failed to send ASSOCIATE command\n");
 		return -1;
@@ -1706,7 +2105,7 @@ static void ipw_eeprom_init_sram(struct 
 
 	/* read entire contents of eeprom into private buffer */
 	for (i = 0; i < 128; i++)
-		eeprom[i] = eeprom_read_u16(priv, (u8) i);
+		eeprom[i] = le16_to_cpu(eeprom_read_u16(priv, (u8) i));
 
 	/*
 	   If the data looks correct, then copy it to our private
@@ -2001,6 +2400,9 @@ static void ipw_remove_current_network(s
 {
 	struct list_head *element, *safe;
 	struct ieee80211_network *network = NULL;
+	unsigned long flags;
+
+	spin_lock_irqsave(&priv->ieee->lock, flags);
 	list_for_each_safe(element, safe, &priv->ieee->network_list) {
 		network = list_entry(element, struct ieee80211_network, list);
 		if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
@@ -2009,6 +2411,7 @@ static void ipw_remove_current_network(s
 				      &priv->ieee->network_free_list);
 		}
 	}
+	spin_unlock_irqrestore(&priv->ieee->lock, flags);
 }
 
 /**
@@ -2158,7 +2561,8 @@ static int ipw_load_ucode(struct ipw_pri
 	 */
 	/* load new ipw uCode */
 	for (i = 0; i < len / 2; i++)
-		ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE, image[i]);
+		ipw_write_reg16(priv, CX2_BASEBAND_CONTROL_STORE,
+				cpu_to_le16(image[i]));
 
 	/* enable DINO */
 	ipw_write_reg8(priv, CX2_BASEBAND_CONTROL_STATUS, 0);
@@ -2181,7 +2585,8 @@ static int ipw_load_ucode(struct ipw_pri
 
 		for (i = 0; i < ARRAY_SIZE(response_buffer); i++)
 			response_buffer[i] =
-			    ipw_read_reg32(priv, CX2_BASEBAND_RX_FIFO_READ);
+			    le32_to_cpu(ipw_read_reg32(priv,
+						       CX2_BASEBAND_RX_FIFO_READ));
 		memcpy(&priv->dino_alive, response_buffer,
 		       sizeof(priv->dino_alive));
 		if (priv->dino_alive.alive_command == 1
@@ -2250,13 +2655,14 @@ static int ipw_load_firmware(struct ipw_
 		 * offeset*/
 		/* Dma loading */
 		rc = ipw_fw_dma_add_buffer(priv, shared_phys + offset,
-					   chunk->address, chunk->length);
+					   le32_to_cpu(chunk->address),
+					   le32_to_cpu(chunk->length));
 		if (rc) {
 			IPW_DEBUG_INFO("dmaAddBuffer Failed\n");
 			goto out;
 		}
 
-		offset += chunk->length;
+		offset += le32_to_cpu(chunk->length);
 	} while (offset < len);
 
 	/* Run the DMA and wait for the answer */
@@ -2351,14 +2757,17 @@ static int ipw_init_nic(struct ipw_priv 
 static int ipw_reset_nic(struct ipw_priv *priv)
 {
 	int rc = 0;
+	unsigned long flags;
 
 	IPW_DEBUG_TRACE(">>\n");
 
 	rc = ipw_init_nic(priv);
 
+	spin_lock_irqsave(&priv->lock, flags);
 	/* Clear the 'host command active' bit... */
 	priv->status &= ~STATUS_HCMD_ACTIVE;
 	wake_up_interruptible(&priv->wait_command_queue);
+	spin_unlock_irqrestore(&priv->lock, flags);
 
 	IPW_DEBUG_TRACE("<<\n");
 	return rc;
@@ -2378,17 +2787,18 @@ static int ipw_get_fw(struct ipw_priv *p
 	}
 
 	header = (struct fw_header *)(*fw)->data;
-	if (IPW_FW_MAJOR(header->version) != IPW_FW_MAJOR_VERSION) {
+	if (IPW_FW_MAJOR(le32_to_cpu(header->version)) != IPW_FW_MAJOR_VERSION) {
 		IPW_ERROR("'%s' firmware version not compatible (%d != %d)\n",
 			  name,
-			  IPW_FW_MAJOR(header->version), IPW_FW_MAJOR_VERSION);
+			  IPW_FW_MAJOR(le32_to_cpu(header->version)),
+			  IPW_FW_MAJOR_VERSION);
 		return -EINVAL;
 	}
 
 	IPW_DEBUG_INFO("Loading firmware '%s' file v%d.%d (%zd bytes)\n",
 		       name,
-		       IPW_FW_MAJOR(header->version),
-		       IPW_FW_MINOR(header->version),
+		       IPW_FW_MAJOR(le32_to_cpu(header->version)),
+		       IPW_FW_MINOR(le32_to_cpu(header->version)),
 		       (*fw)->size - sizeof(struct fw_header));
 	return 0;
 }
@@ -2414,6 +2824,7 @@ static inline void ipw_rx_queue_reset(st
 			pci_unmap_single(priv->pci_dev, rxq->pool[i].dma_addr,
 					 CX2_RX_BUF_SIZE, PCI_DMA_FROMDEVICE);
 			dev_kfree_skb(rxq->pool[i].skb);
+			rxq->pool[i].skb = NULL;
 		}
 		list_add_tail(&rxq->pool[i].list, &rxq->rx_used);
 	}
@@ -2769,16 +3180,18 @@ static void ipw_queue_tx_free_tfd(struct
 		return;
 
 	/* sanity check */
-	if (bd->u.data.num_chunks > NUM_TFD_CHUNKS) {
-		IPW_ERROR("Too many chunks: %i\n", bd->u.data.num_chunks);
+	if (le32_to_cpu(bd->u.data.num_chunks) > NUM_TFD_CHUNKS) {
+		IPW_ERROR("Too many chunks: %i\n",
+			  le32_to_cpu(bd->u.data.num_chunks));
 		/** @todo issue fatal error, it is quite serious situation */
 		return;
 	}
 
 	/* unmap chunks if any */
-	for (i = 0; i < bd->u.data.num_chunks; i++) {
-		pci_unmap_single(dev, bd->u.data.chunk_ptr[i],
-				 bd->u.data.chunk_len[i], PCI_DMA_TODEVICE);
+	for (i = 0; i < le32_to_cpu(bd->u.data.num_chunks); i++) {
+		pci_unmap_single(dev, le32_to_cpu(bd->u.data.chunk_ptr[i]),
+				 le16_to_cpu(bd->u.data.chunk_len[i]),
+				 PCI_DMA_TODEVICE);
 		if (txq->txb[txq->q.last_used]) {
 			ieee80211_txb_free(txq->txb[txq->q.last_used]);
 			txq->txb[txq->q.last_used] = NULL;
@@ -2841,9 +3254,8 @@ static void inline __maybe_wake_tx(struc
 		switch (priv->port_type) {
 		case DCR_TYPE_MU_BSS:
 		case DCR_TYPE_MU_IBSS:
-			if (!(priv->status & STATUS_ASSOCIATED)) {
+			if (!(priv->status & STATUS_ASSOCIATED))
 				return;
-			}
 		}
 		netif_wake_queue(priv->net_dev);
 	}
@@ -3307,8 +3719,13 @@ static inline void ipw_handle_missed_bea
 			  IPW_DL_STATE,
 			  "Missed beacon: %d - disassociate\n", missed_count);
 		priv->status &= ~STATUS_ROAMING;
-		if (priv->status & STATUS_SCANNING)
+		if (priv->status & STATUS_SCANNING) {
+			IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
+				  IPW_DL_STATE,
+				  "Aborting scan with missed beacon.\n");
 			queue_work(priv->workqueue, &priv->abort_scan);
+		}
+
 		queue_work(priv->workqueue, &priv->disassociate);
 		return;
 	}
@@ -3342,6 +3759,8 @@ static inline void ipw_handle_missed_bea
 		 * stuck (only if we aren't roaming --
 		 * otherwise we'll never scan more than 2 or 3
 		 * channels..) */
+		IPW_DEBUG(IPW_DL_INFO | IPW_DL_NOTIF |
+			  IPW_DL_STATE, "Aborting scan with missed beacon.\n");
 		queue_work(priv->workqueue, &priv->abort_scan);
 	}
 
@@ -3356,6 +3775,8 @@ static inline void ipw_handle_missed_bea
 static inline void ipw_rx_notification(struct ipw_priv *priv,
 				       struct ipw_rx_notification *notif)
 {
+	notif->size = le16_to_cpu(notif->size);
+
 	IPW_DEBUG_NOTIF("type = %i (%d bytes)\n", notif->subtype, notif->size);
 
 	switch (notif->subtype) {
@@ -3400,29 +3821,8 @@ static inline void ipw_rx_notification(s
 					priv->status &= ~STATUS_ASSOCIATING;
 					priv->status |= STATUS_ASSOCIATED;
 
-					netif_carrier_on(priv->net_dev);
-					if (netif_queue_stopped(priv->net_dev)) {
-						IPW_DEBUG_NOTIF
-						    ("waking queue\n");
-						netif_wake_queue(priv->net_dev);
-					} else {
-						IPW_DEBUG_NOTIF
-						    ("starting queue\n");
-						netif_start_queue(priv->
-								  net_dev);
-					}
+					schedule_work(&priv->link_up);
 
-					ipw_reset_stats(priv);
-					/* Ensure the rate is updated immediately */
-					priv->last_rate =
-					    ipw_get_current_rate(priv);
-					schedule_work(&priv->gather_stats);
-					notify_wx_assoc_event(priv);
-
-/*			queue_delayed_work(priv->workqueue,
-					   &priv->request_scan,
-					   SCAN_ASSOCIATED_INTERVAL);
-*/
 					break;
 				}
 
@@ -3455,12 +3855,7 @@ static inline void ipw_rx_notification(s
 						      STATUS_AUTH |
 						      STATUS_ASSOCIATED);
 
-						netif_carrier_off(priv->
-								  net_dev);
-						netif_stop_queue(priv->net_dev);
-						queue_work(priv->workqueue,
-							   &priv->request_scan);
-						notify_wx_assoc_event(priv);
+						schedule_work(&priv->link_down);
 						break;
 					}
 
@@ -3506,31 +3901,8 @@ static inline void ipw_rx_notification(s
 					      STATUS_ASSOCIATING |
 					      STATUS_ASSOCIATED | STATUS_AUTH);
 
-					netif_stop_queue(priv->net_dev);
-					if (!(priv->status & STATUS_ROAMING)) {
-						netif_carrier_off(priv->
-								  net_dev);
-						notify_wx_assoc_event(priv);
-
-						/* Cancel any queued work ... */
-						cancel_delayed_work(&priv->
-								    request_scan);
-						cancel_delayed_work(&priv->
-								    adhoc_check);
-
-						/* Queue up another scan... */
-						queue_work(priv->workqueue,
-							   &priv->request_scan);
-
-						cancel_delayed_work(&priv->
-								    gather_stats);
-					} else {
-						priv->status |= STATUS_ROAMING;
-						queue_work(priv->workqueue,
-							   &priv->request_scan);
-					}
+					schedule_work(&priv->link_down);
 
-					ipw_reset_stats(priv);
 					break;
 				}
 
@@ -3576,11 +3948,7 @@ static inline void ipw_rx_notification(s
 						  STATUS_AUTH |
 						  STATUS_ASSOCIATED);
 
-				netif_carrier_off(priv->net_dev);
-				netif_stop_queue(priv->net_dev);
-				queue_work(priv->workqueue,
-					   &priv->request_scan);
-				notify_wx_assoc_event(priv);
+				schedule_work(&priv->link_down);
 				break;
 
 			case CMAS_TX_AUTH_SEQ_1:
@@ -3682,6 +4050,10 @@ static inline void ipw_rx_notification(s
 			} else if (priv->status & STATUS_SCAN_PENDING)
 				queue_work(priv->workqueue,
 					   &priv->request_scan);
+			else if (priv->config & CFG_BACKGROUND_SCAN
+				 && priv->status & STATUS_ASSOCIATED)
+				queue_delayed_work(priv->workqueue,
+						   &priv->request_scan, HZ);
 
 			priv->ieee->scans++;
 			break;
@@ -3690,13 +4062,13 @@ static inline void ipw_rx_notification(s
 	case HOST_NOTIFICATION_STATUS_FRAG_LENGTH:{
 			struct notif_frag_length *x = &notif->u.frag_len;
 
-			if (notif->size == sizeof(*x)) {
-				IPW_ERROR("Frag length: %d\n", x->frag_length);
-			} else {
+			if (notif->size == sizeof(*x))
+				IPW_ERROR("Frag length: %d\n",
+					  le16_to_cpu(x->frag_length));
+			else
 				IPW_ERROR("Frag length of wrong size %d "
 					  "(should be %zd)\n",
 					  notif->size, sizeof(*x));
-			}
 			break;
 		}
 
@@ -3722,11 +4094,9 @@ static inline void ipw_rx_notification(s
 	case HOST_NOTIFICATION_DINO_CONFIG_RESPONSE:{
 			IPW_ERROR("Dino config\n");
 			if (priv->hcmd
-			    && priv->hcmd->cmd == HOST_CMD_DINO_CONFIG) {
-				/* TODO: Do anything special? */
-			} else {
+			    && priv->hcmd->cmd != HOST_CMD_DINO_CONFIG)
 				IPW_ERROR("Unexpected DINO_CONFIG_RESPONSE\n");
-			}
+
 			break;
 		}
 
@@ -3739,8 +4109,11 @@ static inline void ipw_rx_notification(s
 				break;
 			}
 
-			if (x->state == HOST_NOTIFICATION_STATUS_BEACON_MISSING)
-				ipw_handle_missed_beacon(priv, x->number);
+			if (le32_to_cpu(x->state) ==
+			    HOST_NOTIFICATION_STATUS_BEACON_MISSING)
+				ipw_handle_missed_beacon(priv,
+							 le32_to_cpu(x->
+								     number));
 
 			break;
 		}
@@ -3779,7 +4152,8 @@ static inline void ipw_rx_notification(s
 	case HOST_NOTIFICATION_NOISE_STATS:{
 			if (notif->size == sizeof(u32)) {
 				priv->last_noise =
-				    (u8) (notif->u.noise.value & 0xff);
+				    (u8) (le32_to_cpu(notif->u.noise.value) &
+					  0xff);
 				average_add(&priv->average_noise,
 					    priv->last_noise);
 				break;
@@ -3896,9 +4270,8 @@ static int ipw_queue_tx_reclaim(struct i
 		priv->tx_packets++;
 	}
       done:
-	if (ipw_queue_space(q) > q->low_mark && qindex >= 0) {
+	if (ipw_queue_space(q) > q->low_mark && qindex >= 0)
 		__maybe_wake_tx(priv);
-	}
 	used = q->first_empty - q->last_used;
 	if (used < 0)
 		used += q->n_bd;
@@ -4217,13 +4590,16 @@ static int ipw_compatible_rates(struct i
 	num_rates = min(network->rates_len, (u8) IPW_MAX_RATES);
 	rates->num_rates = 0;
 	for (i = 0; i < num_rates; i++) {
-		if (!ipw_is_rate_in_mask
-		    (priv, network->mode, network->rates[i])) {
+		if (!ipw_is_rate_in_mask(priv, network->mode,
+					 network->rates[i])) {
+
 			if (network->rates[i] & IEEE80211_BASIC_RATE_MASK) {
-				IPW_DEBUG_SCAN
-				    ("Basic rate %02X masked: 0x%08X\n",
-				     network->rates[i], priv->rates_mask);
-				return 0;
+				IPW_DEBUG_SCAN("Adding masked mandatory "
+					       "rate %02X\n",
+					       network->rates[i]);
+				rates->supported_rates[rates->num_rates++] =
+				    network->rates[i];
+				continue;
 			}
 
 			IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
@@ -4234,16 +4610,18 @@ static int ipw_compatible_rates(struct i
 		rates->supported_rates[rates->num_rates++] = network->rates[i];
 	}
 
-	num_rates =
-	    min(network->rates_ex_len, (u8) (IPW_MAX_RATES - num_rates));
+	num_rates = min(network->rates_ex_len,
+			(u8) (IPW_MAX_RATES - num_rates));
 	for (i = 0; i < num_rates; i++) {
-		if (!ipw_is_rate_in_mask
-		    (priv, network->mode, network->rates_ex[i])) {
+		if (!ipw_is_rate_in_mask(priv, network->mode,
+					 network->rates_ex[i])) {
 			if (network->rates_ex[i] & IEEE80211_BASIC_RATE_MASK) {
-				IPW_DEBUG_SCAN
-				    ("Basic rate %02X masked: 0x%08X\n",
-				     network->rates_ex[i], priv->rates_mask);
-				return 0;
+				IPW_DEBUG_SCAN("Adding masked mandatory "
+					       "rate %02X\n",
+					       network->rates_ex[i]);
+				rates->supported_rates[rates->num_rates++] =
+				    network->rates[i];
+				continue;
 			}
 
 			IPW_DEBUG_SCAN("Rate %02X masked : 0x%08X\n",
@@ -4531,9 +4909,7 @@ static void ipw_adhoc_create(struct ipw_
 	 * FW fatal error.
 	 */
 	network->mode = is_valid_channel(priv->ieee->mode, priv->channel);
-	if (network->mode) {
-		network->channel = priv->channel;
-	} else {
+	if (!network->mode) {
 		IPW_WARNING("Overriding invalid channel\n");
 		if (priv->ieee->mode & IEEE_A) {
 			network->mode = IEEE_A;
@@ -4572,10 +4948,8 @@ static void ipw_adhoc_create(struct ipw_
 	network->beacon_interval = 100;	/* Default */
 	network->listen_interval = 10;	/* Default */
 	network->atim_window = 0;	/* Default */
-#ifdef CONFIG_IEEE80211_WPA
 	network->wpa_ie_len = 0;
 	network->rsn_ie_len = 0;
-#endif				/* CONFIG_IEEE80211_WPA */
 }
 
 static void ipw_send_wep_keys(struct ipw_priv *priv)
@@ -4593,9 +4967,9 @@ static void ipw_send_wep_keys(struct ipw
 
 	for (i = 0; i < 4; i++) {
 		key->key_index = i;
-		if (!(priv->sec.flags & (1 << i))) {
+		if (!(priv->sec.flags & (1 << i)))
 			key->key_size = 0;
-		} else {
+		else {
 			key->key_size = priv->sec.key_sizes[i];
 			memcpy(key->key, priv->sec.keys[i], key->key_size);
 		}
@@ -4752,9 +5126,10 @@ static int ipw_request_scan(struct ipw_p
 	}
 
 	if (priv->status & STATUS_SCANNING) {
-		IPW_DEBUG_HC("Concurrent scan requested.  Aborting first.\n");
+		IPW_DEBUG_HC("Concurrent scan requested.  Ignoring.\n");
+//              IPW_DEBUG_HC("Concurrent scan requested.  Aborting first.\n");
 		priv->status |= STATUS_SCAN_PENDING;
-		ipw_abort_scan(priv);
+//              ipw_abort_scan(priv);
 		return 0;
 	}
 
@@ -4772,11 +5147,12 @@ static int ipw_request_scan(struct ipw_p
 
 	memset(&scan, 0, sizeof(scan));
 
-	scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = 20;
-	scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] = 20;
-	scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 20;
+	scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_SCAN] = cpu_to_le16(20);
+	scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
+	    cpu_to_le16(20);
+	scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(20);
 
-	scan.full_scan_index = ieee80211_get_scans(priv->ieee);
+	scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
 
 #ifdef CONFIG_IPW_MONITOR
 	if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
@@ -4798,7 +5174,8 @@ static int ipw_request_scan(struct ipw_p
 		ipw_set_scan_type(&scan, channel_index,
 				  IPW_SCAN_PASSIVE_FULL_DWELL_SCAN);
 
-		scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = 2000;
+		scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] =
+		    cpu_to_le16(2000);
 	} else {
 #endif				/* CONFIG_IPW_MONITOR */
 		/* If we are roaming, then make this a directed scan for the current
@@ -4807,7 +5184,7 @@ static int ipw_request_scan(struct ipw_p
 		if ((priv->status & STATUS_ROAMING)
 		    || (!(priv->status & STATUS_ASSOCIATED)
 			&& (priv->config & CFG_STATIC_ESSID)
-			&& (scan.full_scan_index % 2))) {
+			&& (le32_to_cpu(scan.full_scan_index) % 2))) {
 			err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
 			if (err) {
 				IPW_DEBUG_HC
@@ -4882,7 +5259,6 @@ static int ipw_request_scan(struct ipw_p
 
 /* Support for wpa_supplicant. Will be replaced with WEXT once
  * they get WPA support. */
-#ifdef CONFIG_IEEE80211_WPA
 
 /* following definitions must match definitions in driver_ipw.c */
 
@@ -4959,6 +5335,7 @@ static int ipw_wpa_enable(struct ipw_pri
 	} else {
 		sec.level = SEC_LEVEL_0;
 		sec.enabled = 0;
+		ieee->wpa_ie_len = 0;
 	}
 
 	if (ieee->set_security)
@@ -4999,6 +5376,8 @@ static int ipw_wpa_set_auth_algs(struct 
 static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_crypt_data *crypt;
+	unsigned long flags;
 	int ret = 0;
 
 	switch (name) {
@@ -5007,7 +5386,22 @@ static int ipw_wpa_set_param(struct net_
 		break;
 
 	case IPW_PARAM_TKIP_COUNTERMEASURES:
-		priv->ieee->tkip_countermeasures = value;
+		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
+			IPW_WARNING("Can't set TKIP countermeasures: "
+				    "crypt not set!\n");
+			break;
+		}
+
+		flags = crypt->ops->get_flags(crypt->priv);
+
+		if (value)
+			flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+		else
+			flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+
+		crypt->ops->set_flags(flags, crypt->priv);
+
 		break;
 
 	case IPW_PARAM_DROP_UNENCRYPTED:
@@ -5313,7 +5707,6 @@ static int ipw_wpa_supplicant(struct net
 	kfree(param);
 	return ret;
 }
-#endif				/* CONFIG_IEEE80211_WPA */
 
 static int ipw_associate_network(struct ipw_priv *priv,
 				 struct ieee80211_network *network,
@@ -5346,13 +5739,11 @@ static int ipw_associate_network(struct 
 	if (priv->capability & CAP_PRIVACY_ON)
 		ipw_send_wep_keys(priv);
 
-#ifdef CONFIG_IEEE80211_WPA
-	if (priv->ieee->wpa_enabled) {
+	if (priv->ieee->wpa_ie_len) {
 		priv->assoc_request.policy_support = 0x02;	/* RSN active */
 		ipw_set_rsn_capa(priv, priv->ieee->wpa_ie,
 				 priv->ieee->wpa_ie_len);
 	}
-#endif
 
 	/*
 	 * It is valid for our ieee device to support multiple modes, but
@@ -5511,12 +5902,15 @@ static void ipw_roam(void *data)
 	if (priv->status & STATUS_ASSOCIATED) {
 		/* First pass through ROAM process -- look for a better
 		 * network */
+		unsigned long flags;
 		u8 rssi = priv->assoc_network->stats.rssi;
 		priv->assoc_network->stats.rssi = -128;
+		spin_lock_irqsave(&priv->ieee->lock, flags);
 		list_for_each_entry(network, &priv->ieee->network_list, list) {
 			if (network != priv->assoc_network)
 				ipw_best_network(priv, &match, network, 1);
 		}
+		spin_unlock_irqrestore(&priv->ieee->lock, flags);
 		priv->assoc_network->stats.rssi = rssi;
 
 		if (match.network == priv->assoc_network) {
@@ -5549,6 +5943,7 @@ static void ipw_associate(void *data)
 	};
 	struct ipw_supported_rates *rates;
 	struct list_head *element;
+	unsigned long flags;
 
 	if (!(priv->config & CFG_ASSOCIATE) &&
 	    !(priv->config & (CFG_STATIC_ESSID |
@@ -5557,6 +5952,8 @@ static void ipw_associate(void *data)
 		return;
 	}
 
+	/* Protect our use of the network_list */
+	spin_lock_irqsave(&priv->ieee->lock, flags);
 	list_for_each_entry(network, &priv->ieee->network_list, list)
 	    ipw_best_network(priv, &match, network, 0);
 
@@ -5567,6 +5964,7 @@ static void ipw_associate(void *data)
 	    priv->ieee->iw_mode == IW_MODE_ADHOC &&
 	    priv->config & CFG_ADHOC_CREATE &&
 	    priv->config & CFG_STATIC_ESSID &&
+	    priv->config & CFG_STATIC_CHANNEL &&
 	    !list_empty(&priv->ieee->network_free_list)) {
 		element = priv->ieee->network_free_list.next;
 		network = list_entry(element, struct ieee80211_network, list);
@@ -5575,14 +5973,16 @@ static void ipw_associate(void *data)
 		list_del(element);
 		list_add_tail(&network->list, &priv->ieee->network_list);
 	}
+	spin_unlock_irqrestore(&priv->ieee->lock, flags);
 
 	/* If we reached the end of the list, then we don't have any valid
 	 * matching APs */
 	if (!network) {
 		ipw_debug_config(priv);
 
-		queue_delayed_work(priv->workqueue, &priv->request_scan,
-				   SCAN_INTERVAL);
+		if (!(priv->status & STATUS_SCANNING))
+			queue_delayed_work(priv->workqueue, &priv->request_scan,
+					   SCAN_INTERVAL);
 
 		return;
 	}
@@ -5601,7 +6001,7 @@ static inline void ipw_handle_data_packe
 
 	/* We only process data packets if the
 	 * interface is open */
-	if (unlikely((pkt->u.frame.length + IPW_RX_FRAME_SIZE) >
+	if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
 		     skb_tailroom(rxb->skb))) {
 		priv->ieee->stats.rx_errors++;
 		priv->wstats.discard.misc++;
@@ -5618,14 +6018,16 @@ static inline void ipw_handle_data_packe
 	skb_reserve(rxb->skb, offsetof(struct ipw_rx_packet, u.frame.data));
 
 	/* Set the size of the skb to the size of the frame */
-	skb_put(rxb->skb, pkt->u.frame.length);
+	skb_put(rxb->skb, le16_to_cpu(pkt->u.frame.length));
 
 	IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
 
 	if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
 		priv->ieee->stats.rx_errors++;
-	else			/* ieee80211_rx succeeded, so it now owns the SKB */
+	else {			/* ieee80211_rx succeeded, so it now owns the SKB */
 		rxb->skb = NULL;
+		ipw_led_activity_on(priv);
+	}
 }
 
 static inline int is_network_packet(struct ipw_priv *priv,
@@ -5634,23 +6036,29 @@ static inline int is_network_packet(stru
 	/* Filter incoming packets to determine if they are targetted toward
 	 * this network, discarding packets coming from ourselves */
 	switch (priv->ieee->iw_mode) {
-	case IW_MODE_ADHOC:
+	case IW_MODE_ADHOC:	/* Header: Dest. | Source    | BSSID */
+		/* {broad,multi}cast packets to our IBSS go through */
 		if (is_broadcast_ether_addr(header->addr1) ||
 		    is_multicast_ether_addr(header->addr1))
 			return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
-		else
-			return memcmp(header->addr1, priv->net_dev->dev_addr,
-				      ETH_ALEN);
+
+		/* packets to our adapter go through */
+		return !memcmp(header->addr1, priv->net_dev->dev_addr,
+			       ETH_ALEN);
 		break;
-	case IW_MODE_INFRA:
-		if (is_broadcast_ether_addr(header->addr3) ||
-		    is_multicast_ether_addr(header->addr3))
-			return !memcmp(header->addr1, priv->bssid, ETH_ALEN);
-		else
-			return memcmp(header->addr3, priv->net_dev->dev_addr,
-				      ETH_ALEN);
+
+	case IW_MODE_INFRA:	/* Header: Dest. | AP{BSSID} | Source */
+		/* {broad,multi}cast packets to our IBSS go through */
+		if (is_broadcast_ether_addr(header->addr1) ||
+		    is_multicast_ether_addr(header->addr1))
+			return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
+
+		/* packets to our adapter go through */
+		return !memcmp(header->addr1, priv->net_dev->dev_addr,
+			       ETH_ALEN);
 		break;
 	}
+
 	return 1;
 }
 
@@ -5695,7 +6103,7 @@ static void ipw_rx(struct ipw_priv *priv
 				struct ieee80211_rx_stats stats = {
 					.rssi = pkt->u.frame.rssi_dbm -
 					    IPW_RSSI_TO_DBM,
-					.signal = pkt->u.frame.signal,
+					/* .signal = le16_to_cpu(pkt->u.frame.signal), */
 					.rate = pkt->u.frame.rate,
 					.mac_time = jiffies,
 					.received_channel =
@@ -5705,7 +6113,7 @@ static void ipw_rx(struct ipw_priv *priv
 					     control & (1 << 0)) ?
 					    IEEE80211_24GHZ_BAND :
 					    IEEE80211_52GHZ_BAND,
-					.len = pkt->u.frame.length,
+					.len = le16_to_cpu(pkt->u.frame.length),
 				};
 
 				if (stats.rssi != 0)
@@ -5746,9 +6154,10 @@ static void ipw_rx(struct ipw_priv *priv
 				}
 
 				IPW_DEBUG_RX("Frame: len=%u\n",
-					     pkt->u.frame.length);
+					     le16_to_cpu(pkt->u.frame.length));
 
-				if (pkt->u.frame.length < frame_hdr_len(header)) {
+				if (le16_to_cpu(pkt->u.frame.length) <
+				    frame_hdr_len(header)) {
 					IPW_DEBUG_DROP
 					    ("Received packet is too small. "
 					     "Dropping.\n");
@@ -5757,19 +6166,20 @@ static void ipw_rx(struct ipw_priv *priv
 					break;
 				}
 
-				switch (WLAN_FC_GET_TYPE(header->frame_ctl)) {
+				switch (WLAN_FC_GET_TYPE
+					(le16_to_cpu(header->frame_ctl))) {
 				case IEEE80211_FTYPE_MGMT:
 					ieee80211_rx_mgt(priv->ieee, header,
 							 &stats);
 					if (priv->ieee->iw_mode == IW_MODE_ADHOC
 					    &&
 					    ((WLAN_FC_GET_STYPE
-					      (header->frame_ctl) ==
-					      IEEE80211_STYPE_PROBE_RESP)
+					      (le16_to_cpu(header->frame_ctl))
+					      == IEEE80211_STYPE_PROBE_RESP)
 					     ||
 					     (WLAN_FC_GET_STYPE
-					      (header->frame_ctl) ==
-					      IEEE80211_STYPE_BEACON))
+					      (le16_to_cpu(header->frame_ctl))
+					      == IEEE80211_STYPE_BEACON))
 					    && !memcmp(header->addr3,
 						       priv->bssid, ETH_ALEN))
 						ipw_add_station(priv,
@@ -5852,7 +6262,9 @@ static int ipw_wx_get_name(struct net_de
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	if (!(priv->status & STATUS_ASSOCIATED))
+	if (priv->status & STATUS_RF_KILL_MASK) {
+		strcpy(wrqu->name, "radio off");
+	} else if (!(priv->status & STATUS_ASSOCIATED))
 		strcpy(wrqu->name, "unassociated");
 	else
 		snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
@@ -5892,9 +6304,8 @@ static int ipw_set_channel(struct ipw_pr
 	if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
 		IPW_DEBUG_ASSOC("Disassociating due to channel change.\n");
 		ipw_disassociate(priv);
-	} else {
+	} else if (!(priv->status & (STATUS_SCANNING)))
 		ipw_associate(priv);
-	}
 
 	return 0;
 }
@@ -5986,9 +6397,8 @@ static int ipw_wx_set_mode(struct net_de
 #ifdef CONFIG_PM
 	/* Free the existing firmware and reset the fw_loaded
 	 * flag so ipw_load() will bring in the new firmawre */
-	if (fw_loaded) {
+	if (fw_loaded)
 		fw_loaded = 0;
-	}
 
 	release_firmware(bootfw);
 	release_firmware(ucode);
@@ -5997,7 +6407,7 @@ static int ipw_wx_set_mode(struct net_de
 #endif
 
 	priv->ieee->iw_mode = wrqu->mode;
-	ipw_adapter_restart(priv);
+	queue_work(priv->workqueue, &priv->adapter_restart);
 
 	return err;
 }
@@ -6149,9 +6559,8 @@ static int ipw_wx_set_wap(struct net_dev
 	if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
 		IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n");
 		ipw_disassociate(priv);
-	} else {
+	} else if (!(priv->status & (STATUS_SCANNING)))
 		ipw_associate(priv);
-	}
 
 	return 0;
 }
@@ -6220,9 +6629,8 @@ static int ipw_wx_set_essid(struct net_d
 	if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
 		IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n");
 		ipw_disassociate(priv);
-	} else {
+	} else if (!(priv->status & (STATUS_SCANNING)))
 		ipw_associate(priv);
-	}
 
 	return 0;
 }
@@ -6383,10 +6791,10 @@ static int ipw_wx_set_rate(struct net_de
 		if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
 			IPW_DEBUG_ASSOC("Disassociating due to RATE change.\n");
 			ipw_disassociate(priv);
+		} else if (!(priv->status & (STATUS_SCANNING))) {
+			/* We are not yet associated, so kick one off... */
+			ipw_associate(priv);
 		}
-	} else {
-		/* We are not yet associated, so kick one off... */
-		ipw_associate(priv);
 	}
 
 	return 0;
@@ -6635,11 +7043,10 @@ static int ipw_wx_get_power(struct net_d
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 
-	if (!(priv->power_mode & IPW_POWER_ENABLED)) {
+	if (!(priv->power_mode & IPW_POWER_ENABLED))
 		wrqu->power.disabled = 1;
-	} else {
+	else
 		wrqu->power.disabled = 0;
-	}
 
 	IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
 
@@ -6764,6 +7171,9 @@ static int ipw_wx_set_wireless_mode(stru
 	} else
 		ipw_send_supported_rates(priv, &priv->rates);
 
+	/* Update the band LEDs */
+	ipw_led_band_on(priv);
+
 	IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
 		     mode & IEEE_A ? 'a' : '.',
 		     mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
@@ -6870,7 +7280,7 @@ static int ipw_wx_set_monitor(struct net
 	if (enable) {
 		if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
 			priv->net_dev->type = ARPHRD_IEEE80211;
-			ipw_adapter_restart(priv);
+			queue_work(priv->workqueue, &priv->adapter_restart);
 		}
 
 		ipw_set_channel(priv, parms[1]);
@@ -6878,7 +7288,7 @@ static int ipw_wx_set_monitor(struct net
 		if (priv->ieee->iw_mode != IW_MODE_MONITOR)
 			return 0;
 		priv->net_dev->type = ARPHRD_ETHER;
-		ipw_adapter_restart(priv);
+		queue_work(priv->workqueue, &priv->adapter_restart);
 	}
 	return 0;
 }
@@ -6889,7 +7299,7 @@ static int ipw_wx_reset(struct net_devic
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	IPW_DEBUG_WX("RESET\n");
-	ipw_adapter_restart(priv);
+	queue_work(priv->workqueue, &priv->adapter_restart);
 	return 0;
 }
 #endif				// CONFIG_IPW_MONITOR
@@ -6925,6 +7335,10 @@ static iw_handler ipw_wx_handlers[] = {
 	IW_IOCTL(SIOCGIWENCODE) = ipw_wx_get_encode,
 	IW_IOCTL(SIOCSIWPOWER) = ipw_wx_set_power,
 	IW_IOCTL(SIOCGIWPOWER) = ipw_wx_get_power,
+	IW_IOCTL(SIOCSIWSPY) = iw_handler_set_spy,
+	IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
+	IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
+	IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
 };
 
 #define IPW_PRIV_SET_POWER	SIOCIWFIRSTPRIV
@@ -6993,6 +7407,8 @@ static struct iw_handler_def ipw_wx_hand
 	.private_args = ipw_priv_args,
 };
 
+static struct iw_public_data ipw_wx_data;
+
 /*
  * Get wireless statistics.
  * Called by /proc/net/wireless
@@ -7057,7 +7473,7 @@ static inline void init_sys_config(struc
 	sys_config->dot11g_auto_detection = 0;
 	sys_config->enable_cts_to_self = 0;
 	sys_config->bt_coexist_collision_thr = 0;
-	sys_config->pass_noise_stats_to_host = 1;
+	sys_config->pass_noise_stats_to_host = 0;	//1 -- fix for 256
 }
 
 static int ipw_net_open(struct net_device *dev)
@@ -7131,7 +7547,7 @@ static inline void ipw_tx_skb(struct ipw
 	tfd->control_flags.control_bits = TFD_NEED_IRQ_MASK;
 
 	tfd->u.data.cmd_id = DINO_CMD_TX;
-	tfd->u.data.len = txb->payload_size;
+	tfd->u.data.len = cpu_to_le16(txb->payload_size);
 	remaining_bytes = txb->payload_size;
 	if (unlikely(!unicast))
 		tfd->u.data.tx_flags = DCT_FLAG_NO_WEP;
@@ -7149,8 +7565,14 @@ static inline void ipw_tx_skb(struct ipw
 	memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
 
 	/* payload */
-	tfd->u.data.num_chunks = min((u8) (NUM_TFD_CHUNKS - 2), txb->nr_frags);
-	for (i = 0; i < tfd->u.data.num_chunks; i++) {
+	tfd->u.data.num_chunks = cpu_to_le32(min((u8) (NUM_TFD_CHUNKS - 2),
+						 txb->nr_frags));
+	IPW_DEBUG_FRAG("%i fragments being sent as %i chunks.\n",
+		       txb->nr_frags, le32_to_cpu(tfd->u.data.num_chunks));
+	for (i = 0; i < le32_to_cpu(tfd->u.data.num_chunks); i++) {
+		IPW_DEBUG_FRAG("Adding fragment %i of %i (%d bytes).\n",
+			       i, le32_to_cpu(tfd->u.data.num_chunks),
+			       txb->fragments[i]->len - hdr_len);
 		IPW_DEBUG_TX("Dumping TX packet frag %i of %i (%d bytes):\n",
 			     i, tfd->u.data.num_chunks,
 			     txb->fragments[i]->len - hdr_len);
@@ -7158,11 +7580,13 @@ static inline void ipw_tx_skb(struct ipw
 			   txb->fragments[i]->len - hdr_len);
 
 		tfd->u.data.chunk_ptr[i] =
-		    pci_map_single(priv->pci_dev,
-				   txb->fragments[i]->data + hdr_len,
-				   txb->fragments[i]->len - hdr_len,
-				   PCI_DMA_TODEVICE);
-		tfd->u.data.chunk_len[i] = txb->fragments[i]->len - hdr_len;
+		    cpu_to_le32(pci_map_single
+				(priv->pci_dev,
+				 txb->fragments[i]->data + hdr_len,
+				 txb->fragments[i]->len - hdr_len,
+				 PCI_DMA_TODEVICE));
+		tfd->u.data.chunk_len[i] =
+		    cpu_to_le16(txb->fragments[i]->len - hdr_len);
 	}
 
 	if (i != txb->nr_frags) {
@@ -7177,7 +7601,7 @@ static inline void ipw_tx_skb(struct ipw
 		       remaining_bytes);
 		skb = alloc_skb(remaining_bytes, GFP_ATOMIC);
 		if (skb != NULL) {
-			tfd->u.data.chunk_len[i] = remaining_bytes;
+			tfd->u.data.chunk_len[i] = cpu_to_le16(remaining_bytes);
 			for (j = i; j < txb->nr_frags; j++) {
 				int size = txb->fragments[j]->len - hdr_len;
 				printk(KERN_INFO "Adding frag %d %d...\n",
@@ -7188,10 +7612,14 @@ static inline void ipw_tx_skb(struct ipw
 			dev_kfree_skb_any(txb->fragments[i]);
 			txb->fragments[i] = skb;
 			tfd->u.data.chunk_ptr[i] =
-			    pci_map_single(priv->pci_dev, skb->data,
-					   tfd->u.data.chunk_len[i],
-					   PCI_DMA_TODEVICE);
-			tfd->u.data.num_chunks++;
+			    cpu_to_le32(pci_map_single
+					(priv->pci_dev, skb->data,
+					 tfd->u.data.chunk_len[i],
+					 PCI_DMA_TODEVICE));
+
+			tfd->u.data.num_chunks =
+			    cpu_to_le32(le32_to_cpu(tfd->u.data.num_chunks) +
+					1);
 		}
 	}
 
@@ -7227,6 +7655,7 @@ static int ipw_net_hard_start_xmit(struc
 	}
 
 	ipw_tx_skb(priv, txb);
+	ipw_led_activity_on(priv);
 
 	spin_unlock_irqrestore(&priv->lock, flags);
 	return 0;
@@ -7260,7 +7689,7 @@ static int ipw_net_set_mac_address(struc
 	memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
 	printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
 	       priv->net_dev->name, MAC_ARG(priv->mac_addr));
-	ipw_adapter_restart(priv);
+	queue_work(priv->workqueue, &priv->adapter_restart);
 	return 0;
 }
 
@@ -7414,6 +7843,46 @@ static void ipw_rf_kill(void *adapter)
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+void ipw_link_up(struct ipw_priv *priv)
+{
+	netif_carrier_on(priv->net_dev);
+	if (netif_queue_stopped(priv->net_dev)) {
+		IPW_DEBUG_NOTIF("waking queue\n");
+		netif_wake_queue(priv->net_dev);
+	} else {
+		IPW_DEBUG_NOTIF("starting queue\n");
+		netif_start_queue(priv->net_dev);
+	}
+
+	ipw_reset_stats(priv);
+	/* Ensure the rate is updated immediately */
+	priv->last_rate = ipw_get_current_rate(priv);
+	ipw_gather_stats(priv);
+	ipw_led_link_up(priv);
+	notify_wx_assoc_event(priv);
+
+	if (priv->config & CFG_BACKGROUND_SCAN)
+		queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
+}
+
+void ipw_link_down(struct ipw_priv *priv)
+{
+	ipw_led_link_down(priv);
+	netif_carrier_off(priv->net_dev);
+	netif_stop_queue(priv->net_dev);
+	notify_wx_assoc_event(priv);
+
+	/* Cancel any queued work ... */
+	cancel_delayed_work(&priv->request_scan);
+	cancel_delayed_work(&priv->adhoc_check);
+	cancel_delayed_work(&priv->gather_stats);
+
+	ipw_reset_stats(priv);
+
+	/* Queue up another scan... */
+	queue_work(priv->workqueue, &priv->request_scan);
+}
+
 static int ipw_setup_deferred_work(struct ipw_priv *priv)
 {
 	int ret = 0;
@@ -7436,6 +7905,13 @@ static int ipw_setup_deferred_work(struc
 	INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv);
 	INIT_WORK(&priv->roam, ipw_roam, priv);
 	INIT_WORK(&priv->scan_check, ipw_scan_check, priv);
+	INIT_WORK(&priv->link_up, (void (*)(void *))ipw_link_up, priv);
+	INIT_WORK(&priv->link_down, (void (*)(void *))ipw_link_down, priv);
+	INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_led_link_on, priv);
+	INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_led_link_off,
+		  priv);
+	INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_led_activity_off,
+		  priv);
 
 	tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
 		     ipw_irq_tasklet, (unsigned long)priv);
@@ -7636,8 +8112,9 @@ static int ipw_up(struct ipw_priv *priv)
 		rc = ipw_config(priv);
 		if (!rc) {
 			IPW_DEBUG_INFO("Configured device on count %i\n", i);
+			ipw_led_init(priv);
+			ipw_led_radio_on(priv);
 			priv->notif_missed_beacons = 0;
-			netif_start_queue(priv->net_dev);
 			return 0;
 		} else {
 			IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n",
@@ -7675,11 +8152,12 @@ static void ipw_down(struct ipw_priv *pr
 	netif_stop_queue(priv->net_dev);
 
 	ipw_stop_nic(priv);
+
+	ipw_led_radio_off(priv);
 }
 
 static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-#ifdef CONFIG_IEEE80211_WPA
 	struct iwreq *wrq = (struct iwreq *)rq;
 	int ret = -1;
 	switch (cmd) {
@@ -7691,8 +8169,6 @@ static int ipw_ioctl(struct net_device *
 		return -EOPNOTSUPP;
 	}
 
-#endif				/* CONFIG_IEEE80211_WPA */
-
 	return -EOPNOTSUPP;
 }
 
@@ -7739,7 +8215,7 @@ static struct pci_device_id card_ids[] =
 	{PCI_VENDOR_ID_INTEL, 0x1043, 0x8086, 0x2762, 0, 0, 0},
 	{PCI_VENDOR_ID_INTEL, 0x104f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
 	{PCI_VENDOR_ID_INTEL, 0x4220, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* BG */
-	{PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* 2225BG */
+	{PCI_VENDOR_ID_INTEL, 0x4221, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* BG */
 	{PCI_VENDOR_ID_INTEL, 0x4223, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* ABG */
 	{PCI_VENDOR_ID_INTEL, 0x4224, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},	/* ABG */
 
@@ -7764,6 +8240,8 @@ static struct attribute *ipw_sysfs_entri
 	&dev_attr_eeprom_delay.attr,
 	&dev_attr_ucode_version.attr,
 	&dev_attr_rtc.attr,
+	&dev_attr_scan_age.attr,
+	&dev_attr_led.attr,
 	NULL
 };
 
@@ -7789,6 +8267,7 @@ static int ipw_pci_probe(struct pci_dev 
 
 	priv = ieee80211_priv(net_dev);
 	priv->ieee = netdev_priv(net_dev);
+
 	priv->net_dev = net_dev;
 	priv->pci_dev = pdev;
 #ifdef CONFIG_IPW_DEBUG
@@ -7843,6 +8322,12 @@ static int ipw_pci_probe(struct pci_dev 
 	}
 
 	/* Initialize module parameter values here */
+
+	/* We default to disabling the LED code as right now it causes
+	 * too many systems to lock up... */
+	if (!led)
+		priv->config |= CFG_NO_LED;
+
 	if (associate)
 		priv->config |= CFG_ASSOCIATE;
 	else
@@ -7893,14 +8378,9 @@ static int ipw_pci_probe(struct pci_dev 
 		priv->adapter = IPW_2915ABG;
 		priv->ieee->mode = IEEE_A | IEEE_G | IEEE_B;
 	} else {
-		if (priv->pci_dev->device == 0x4221)
-			printk(KERN_INFO DRV_NAME
-			       ": Detected Intel PRO/Wireless 2225BG Network "
-			       "Connection\n");
-		else
-			printk(KERN_INFO DRV_NAME
-			       ": Detected Intel PRO/Wireless 2200BG Network "
-			       "Connection\n");
+		printk(KERN_INFO DRV_NAME
+		       ": Detected Intel PRO/Wireless 2200BG Network "
+		       "Connection\n");
 
 		priv->ieee->abg_true = 0;
 		band = IEEE80211_24GHZ_BAND;
@@ -7933,6 +8413,9 @@ static int ipw_pci_probe(struct pci_dev 
 	SET_MODULE_OWNER(net_dev);
 	SET_NETDEV_DEV(net_dev, &pdev->dev);
 
+	ipw_wx_data.spy_data = &priv->ieee->spy_data;
+	ipw_wx_data.ieee80211 = priv->ieee;
+
 	priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
 	priv->ieee->set_security = shim__set_security;
 
@@ -7944,6 +8427,7 @@ static int ipw_pci_probe(struct pci_dev 
 	net_dev->set_multicast_list = ipw_net_set_multicast_list;
 	net_dev->set_mac_address = ipw_net_set_mac_address;
 	net_dev->get_wireless_stats = ipw_get_wireless_stats;
+	net_dev->wireless_data = &ipw_wx_data;
 	net_dev->wireless_handlers = &ipw_wx_handler_def;
 	net_dev->ethtool_ops = &ipw_ethtool_ops;
 	net_dev->irq = pdev->irq;
@@ -7960,12 +8444,12 @@ static int ipw_pci_probe(struct pci_dev 
 	err = register_netdev(net_dev);
 	if (err) {
 		IPW_ERROR("failed to register network device\n");
-		goto out_remove_group;
+		goto out_remove_sysfs;
 	}
 
 	return 0;
 
-      out_remove_group:
+      out_remove_sysfs:
 	sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
       out_release_irq:
 	free_irq(pdev->irq, priv);
@@ -8005,17 +8489,17 @@ static void ipw_pci_remove(struct pci_de
 	}
 	ipw_tx_queue_free(priv);
 
+	ipw_led_shutdown(priv);
+
 	/* ipw_down will ensure that there is no more pending work
 	 * in the workqueue's, so we can safely remove them now. */
-	if (priv->workqueue) {
-		cancel_delayed_work(&priv->adhoc_check);
-		cancel_delayed_work(&priv->gather_stats);
-		cancel_delayed_work(&priv->request_scan);
-		cancel_delayed_work(&priv->rf_kill);
-		cancel_delayed_work(&priv->scan_check);
-		destroy_workqueue(priv->workqueue);
-		priv->workqueue = NULL;
-	}
+	cancel_delayed_work(&priv->adhoc_check);
+	cancel_delayed_work(&priv->gather_stats);
+	cancel_delayed_work(&priv->request_scan);
+	cancel_delayed_work(&priv->rf_kill);
+	cancel_delayed_work(&priv->scan_check);
+	destroy_workqueue(priv->workqueue);
+	priv->workqueue = NULL;
 
 	free_irq(pdev->irq, priv);
 	iounmap(priv->hw_base);
@@ -8138,6 +8622,10 @@ MODULE_PARM_DESC(associate, "auto associ
 module_param(auto_create, int, 0444);
 MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
 
+module_param(led, int, 0444);
+MODULE_PARM_DESC(auto_create,
+		 "enable led control on some systems (default 0 off)\n");
+
 module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
 
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 0680279..1b339cb 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -403,9 +403,9 @@ struct clx2_tx_queue {
 #define RX_FREE_BUFFERS 32
 #define RX_LOW_WATERMARK 8
 
-#define SUP_RATE_11A_MAX_NUM_CHANNELS  (8)
-#define SUP_RATE_11B_MAX_NUM_CHANNELS  (4)
-#define SUP_RATE_11G_MAX_NUM_CHANNELS  (12)
+#define SUP_RATE_11A_MAX_NUM_CHANNELS  8
+#define SUP_RATE_11B_MAX_NUM_CHANNELS  4
+#define SUP_RATE_11G_MAX_NUM_CHANNELS  12
 
 // Used for passing to driver number of successes and failures per rate
 struct rate_histogram {
@@ -890,6 +890,9 @@ struct ipw_cmd {
 #define STATUS_SCANNING         (1<<21)
 #define STATUS_SCAN_ABORTING    (1<<22)
 
+#define STATUS_LED_LINK_ON      (1<<24)
+#define STATUS_LED_ACT_ON       (1<<25)
+
 #define STATUS_INDIRECT_BYTE    (1<<28)	/* sysfs entry configured for access */
 #define STATUS_INDIRECT_DWORD   (1<<29)	/* sysfs entry configured for access */
 #define STATUS_DIRECT_DWORD     (1<<30)	/* sysfs entry configured for access */
@@ -905,6 +908,8 @@ struct ipw_cmd {
 #define CFG_ASSOCIATE           (1<<6)
 #define CFG_FIXED_RATE          (1<<7)
 #define CFG_ADHOC_CREATE        (1<<8)
+#define CFG_NO_LED              (1<<9)
+#define CFG_BACKGROUND_SCAN     (1<<10)
 
 #define CAP_SHARED_KEY          (1<<0)	/* Off = OPEN */
 #define CAP_PRIVACY_ON          (1<<1)	/* Off = No privacy */
@@ -1046,9 +1051,24 @@ struct ipw_priv {
 	struct work_struct abort_scan;
 	struct work_struct roam;
 	struct work_struct scan_check;
+	struct work_struct link_up;
+	struct work_struct link_down;
 
 	struct tasklet_struct irq_tasklet;
 
+	/* LED related variables and work_struct */
+	u8 nic_type;
+	u32 led_activity_on;
+	u32 led_activity_off;
+	u32 led_association_on;
+	u32 led_association_off;
+	u32 led_ofdm_on;
+	u32 led_ofdm_off;
+
+	struct work_struct led_link_on;
+	struct work_struct led_link_off;
+	struct work_struct led_act_off;
+
 #define IPW_2200BG  1
 #define IPW_2915ABG 2
 	u8 adapter;
@@ -1126,6 +1146,8 @@ do { if (ipw_debug_level & (level)) \
 #define IPW_DL_RF_KILL       (1<<17)
 #define IPW_DL_FW_ERRORS     (1<<18)
 
+#define IPW_DL_LED           (1<<19)
+
 #define IPW_DL_ORD           (1<<20)
 
 #define IPW_DL_FRAG          (1<<21)
@@ -1151,6 +1173,7 @@ do { if (ipw_debug_level & (level)) \
 #define IPW_DEBUG_TX(f, a...)     IPW_DEBUG(IPW_DL_TX, f, ## a)
 #define IPW_DEBUG_ISR(f, a...)    IPW_DEBUG(IPW_DL_ISR, f, ## a)
 #define IPW_DEBUG_MANAGEMENT(f, a...) IPW_DEBUG(IPW_DL_MANAGE, f, ## a)
+#define IPW_DEBUG_LED(f, a...) IPW_DEBUG(IPW_DL_LED, f, ## a)
 #define IPW_DEBUG_WEP(f, a...)    IPW_DEBUG(IPW_DL_WEP, f, ## a)
 #define IPW_DEBUG_HC(f, a...) IPW_DEBUG(IPW_DL_HOST_COMMAND, f, ## a)
 #define IPW_DEBUG_FRAG(f, a...) IPW_DEBUG(IPW_DL_FRAG, f, ## a)
@@ -1268,25 +1291,25 @@ do { if (ipw_debug_level & (level)) \
 #define CX2_DMA_I_DMA_CONTROL 0x003000A4
 #define CX2_DMA_I_CB_BASE     0x003000A0
 
-#define CX2_TX_CMD_QUEUE_BD_BASE        (0x00000200)
-#define CX2_TX_CMD_QUEUE_BD_SIZE        (0x00000204)
-#define CX2_TX_QUEUE_0_BD_BASE          (0x00000208)
+#define CX2_TX_CMD_QUEUE_BD_BASE        0x00000200
+#define CX2_TX_CMD_QUEUE_BD_SIZE        0x00000204
+#define CX2_TX_QUEUE_0_BD_BASE          0x00000208
 #define CX2_TX_QUEUE_0_BD_SIZE          (0x0000020C)
-#define CX2_TX_QUEUE_1_BD_BASE          (0x00000210)
-#define CX2_TX_QUEUE_1_BD_SIZE          (0x00000214)
-#define CX2_TX_QUEUE_2_BD_BASE          (0x00000218)
+#define CX2_TX_QUEUE_1_BD_BASE          0x00000210
+#define CX2_TX_QUEUE_1_BD_SIZE          0x00000214
+#define CX2_TX_QUEUE_2_BD_BASE          0x00000218
 #define CX2_TX_QUEUE_2_BD_SIZE          (0x0000021C)
-#define CX2_TX_QUEUE_3_BD_BASE          (0x00000220)
-#define CX2_TX_QUEUE_3_BD_SIZE          (0x00000224)
-#define CX2_RX_BD_BASE                  (0x00000240)
-#define CX2_RX_BD_SIZE                  (0x00000244)
-#define CX2_RFDS_TABLE_LOWER            (0x00000500)
-
-#define CX2_TX_CMD_QUEUE_READ_INDEX     (0x00000280)
-#define CX2_TX_QUEUE_0_READ_INDEX       (0x00000284)
-#define CX2_TX_QUEUE_1_READ_INDEX       (0x00000288)
+#define CX2_TX_QUEUE_3_BD_BASE          0x00000220
+#define CX2_TX_QUEUE_3_BD_SIZE          0x00000224
+#define CX2_RX_BD_BASE                  0x00000240
+#define CX2_RX_BD_SIZE                  0x00000244
+#define CX2_RFDS_TABLE_LOWER            0x00000500
+
+#define CX2_TX_CMD_QUEUE_READ_INDEX     0x00000280
+#define CX2_TX_QUEUE_0_READ_INDEX       0x00000284
+#define CX2_TX_QUEUE_1_READ_INDEX       0x00000288
 #define CX2_TX_QUEUE_2_READ_INDEX       (0x0000028C)
-#define CX2_TX_QUEUE_3_READ_INDEX       (0x00000290)
+#define CX2_TX_QUEUE_3_READ_INDEX       0x00000290
 #define CX2_RX_READ_INDEX               (0x000002A0)
 
 #define CX2_TX_CMD_QUEUE_WRITE_INDEX    (0x00000F80)
@@ -1333,15 +1356,15 @@ do { if (ipw_debug_level & (level)) \
 #define EEPROM_HW_VERSION       (GET_EEPROM_ADDR(0x72,LSB))	/* 2 bytes  */
 
 /* NIC type as found in the one byte EEPROM_NIC_TYPE  offset*/
-#define EEPROM_NIC_TYPE_STANDARD        0
-#define EEPROM_NIC_TYPE_DELL            1
-#define EEPROM_NIC_TYPE_FUJITSU         2
-#define EEPROM_NIC_TYPE_IBM             3
-#define EEPROM_NIC_TYPE_HP              4
+#define EEPROM_NIC_TYPE_0 0
+#define EEPROM_NIC_TYPE_1 1
+#define EEPROM_NIC_TYPE_2 2
+#define EEPROM_NIC_TYPE_3 3
+#define EEPROM_NIC_TYPE_4 4
 
 #define FW_MEM_REG_LOWER_BOUND          0x00300000
 #define FW_MEM_REG_EEPROM_ACCESS        (FW_MEM_REG_LOWER_BOUND + 0x40)
-
+#define CX2_EVENT_REG                   (FW_MEM_REG_LOWER_BOUND + 0x04)
 #define EEPROM_BIT_SK                   (1<<0)
 #define EEPROM_BIT_CS                   (1<<1)
 #define EEPROM_BIT_DI                   (1<<2)
---
0.99.8.GIT


--- NEW FILE 2914-Catch-ipw2200-up-to-equivelancy-with-v1.0.3.txt ---
Subject: [PATCH] Catch ipw2200 up to equivelancy with v1.0.3
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124938584 -0500

* Fix #616 problem with OOPS on module load (thanks to Yi Zhu)
* Fixed problem with led module parameter being described as
  'auto_create'
* Added support to merge between adhoc networks (thanks to Mohamed Abbas)
* Added semaphore lock at the driver's entry points to protect against
  re-entry (thanks to Mohamed Abbas)
* Added semaphore lock to background scheduled driver actions (thanks to
  Mohamed Abbas)
* Changed how signal quality is reported for scan output (thanks to
  Peter Jones)
* Fixed how high/low clamp values of signal quality are reported so a
  more consistent ramp is provided (thanks to Bill Moss)
* Fix #624 problem with duplicate addresses (again)  (thanks to Bernard
  Blackham)
* Fix #385 problem with fragmentation and certain sized packets (thanks
  to Mohamed Abbas)
* Modified iwconfig network name if RF kill is enabled to say 'radio off'
* Fix #382 problem with driver not responding to probe requests in Ad-Hoc
  mode (thanks to Mohamed Abbas)

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |  841 ++++++++++++++++++++++++++++++++--------
 drivers/net/wireless/ipw2200.h |    5 
 2 files changed, 668 insertions(+), 178 deletions(-)

applies-to: 982d4f3de285993749138b0e6e2f2d778b120407
c848d0af404f00835f038e370005733d90a186fd
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index ea7a3dc..0bf1931 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -32,7 +32,7 @@
 
 #include "ipw2200.h"
 
-#define IPW2200_VERSION "1.0.2"
+#define IPW2200_VERSION "1.0.3"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2004 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
@@ -68,9 +68,10 @@ static void ipw_tx_queue_free(struct ipw
 static struct ipw_rx_queue *ipw_rx_queue_alloc(struct ipw_priv *);
 static void ipw_rx_queue_free(struct ipw_priv *, struct ipw_rx_queue *);
 static void ipw_rx_queue_replenish(void *);
-
 static int ipw_up(struct ipw_priv *);
+static void ipw_bg_up(void *);
 static void ipw_down(struct ipw_priv *);
+static void ipw_bg_down(void *);
 static int ipw_config(struct ipw_priv *);
 static int init_supported_rates(struct ipw_priv *priv,
 				struct ipw_supported_rates *prates);
@@ -473,6 +474,11 @@ static void ipw_dump_nic_event_log(struc
 	}
 }
 
+static inline int ipw_is_init(struct ipw_priv *priv)
+{
+	return (priv->status & STATUS_INIT) ? 1 : 0;
+}
+
 static int ipw_get_ordinal(struct ipw_priv *priv, u32 ord, void *val, u32 * len)
 {
 	u32 addr, field_info, field_len, field_count, total_len;
@@ -698,6 +704,14 @@ void ipw_led_link_on(struct ipw_priv *pr
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+static void ipw_bg_led_link_on(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_led_link_on(data);
+	up(&priv->sem);
+}
+
 void ipw_led_link_off(struct ipw_priv *priv)
 {
 	unsigned long flags;
@@ -734,6 +748,14 @@ void ipw_led_link_off(struct ipw_priv *p
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+static void ipw_bg_led_link_off(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_led_link_off(data);
+	up(&priv->sem);
+}
+
 void ipw_led_activity_on(struct ipw_priv *priv)
 {
 	unsigned long flags;
@@ -762,6 +784,7 @@ void ipw_led_activity_on(struct ipw_priv
 
 		priv->status |= STATUS_LED_ACT_ON;
 
+		cancel_delayed_work(&priv->led_act_off);
 		queue_delayed_work(priv->workqueue, &priv->led_act_off,
 				   LD_TIME_ACT_ON);
 	} else {
@@ -801,13 +824,22 @@ void ipw_led_activity_off(struct ipw_pri
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+static void ipw_bg_led_activity_off(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_led_activity_off(data);
+	up(&priv->sem);
+}
+
 void ipw_led_band_on(struct ipw_priv *priv)
 {
 	unsigned long flags;
 	u32 led;
 
 	/* Only nic type 1 supports mode LEDs */
-	if (priv->config & CFG_NO_LED || priv->nic_type != EEPROM_NIC_TYPE_1)
+	if (priv->config & CFG_NO_LED ||
+	    priv->nic_type != EEPROM_NIC_TYPE_1 || !priv->assoc_network)
 		return;
 
 	spin_lock_irqsave(&priv->lock, flags);
@@ -993,7 +1025,9 @@ static ssize_t store_scan_age(struct dev
 			      const char *buf, size_t count)
 {
 	struct ipw_priv *priv = dev_get_drvdata(d);
+#ifdef CONFIG_IPW_DEBUG
 	struct net_device *dev = priv->net_dev;
+#endif
 	char buffer[] = "00000000";
 	unsigned long len =
 	    (sizeof(buffer) - 1) > count ? count : sizeof(buffer) - 1;
@@ -1704,6 +1738,14 @@ static void ipw_adapter_restart(void *ad
 	}
 }
 
+static void ipw_bg_adapter_restart(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_adapter_restart(data);
+	up(&priv->sem);
+}
+
 #define IPW_SCAN_CHECK_WATCHDOG (5 * HZ)
 
 static void ipw_scan_check(void *data)
@@ -1717,6 +1759,14 @@ static void ipw_scan_check(void *data)
 	}
 }
 
+static void ipw_bg_scan_check(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_scan_check(data);
+	up(&priv->sem);
+}
+
 static int ipw_send_scan_request_ext(struct ipw_priv *priv,
 				     struct ipw_scan_request_ext *request)
 {
@@ -2982,6 +3032,8 @@ static int ipw_load(struct ipw_priv *pri
 
 	/* Ensure interrupts are disabled */
 	ipw_write32(priv, CX2_INTA_MASK_R, ~CX2_INTA_MASK_ALL);
+	/* ack pending interrupts */
+	ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
 
 	/* kick start the device */
 	ipw_start_nic(priv);
@@ -3350,9 +3402,21 @@ static void ipw_send_disassociate(struct
 
 }
 
-static void ipw_disassociate(void *data)
+static int ipw_disassociate(void *data)
 {
+	struct ipw_priv *priv = data;
+	if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)))
+		return 0;
 	ipw_send_disassociate(data, 0);
+	return 1;
+}
+
+static void ipw_bg_disassociate(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_disassociate(data);
+	up(&priv->sem);
 }
 
 struct ipw_status_code {
@@ -3571,8 +3635,6 @@ static u32 ipw_get_current_rate(struct i
 	return 0;
 }
 
-#define PERFECT_RSSI (-20)
-#define WORST_RSSI   (-85)
 #define IPW_STATS_INTERVAL (2 * HZ)
 static void ipw_gather_stats(struct ipw_priv *priv)
 {
@@ -3663,19 +3725,19 @@ static void ipw_gather_stats(struct ipw_
 			tx_quality, tx_failures_delta, tx_packets_delta);
 
 	rssi = average_value(&priv->average_rssi);
-	if (rssi > PERFECT_RSSI)
+	signal_quality =
+	    (100 *
+	     (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
+	     (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) -
+	     (priv->ieee->perfect_rssi - rssi) *
+	     (15 * (priv->ieee->perfect_rssi - priv->ieee->worst_rssi) +
+	      62 * (priv->ieee->perfect_rssi - rssi))) /
+	    ((priv->ieee->perfect_rssi - priv->ieee->worst_rssi) *
+	     (priv->ieee->perfect_rssi - priv->ieee->worst_rssi));
+	if (signal_quality > 100)
 		signal_quality = 100;
-	else if (rssi < WORST_RSSI)
+	else if (signal_quality < 1)
 		signal_quality = 0;
-	else			/* qual = 100a^2 - 15ab + 62b^2 / a^2 */
-		signal_quality =
-		    (100 *
-		     (PERFECT_RSSI - WORST_RSSI) *
-		     (PERFECT_RSSI - WORST_RSSI) -
-		     (PERFECT_RSSI - rssi) *
-		     (15 * (PERFECT_RSSI - WORST_RSSI) +
-		      62 * (PERFECT_RSSI - rssi))) /
-		    ((PERFECT_RSSI - WORST_RSSI) * (PERFECT_RSSI - WORST_RSSI));
 
 	IPW_DEBUG_STATS("Signal level : %3d%% (%d dBm)\n",
 			signal_quality, rssi);
@@ -3705,6 +3767,14 @@ static void ipw_gather_stats(struct ipw_
 			   IPW_STATS_INTERVAL);
 }
 
+static void ipw_bg_gather_stats(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_gather_stats(data);
+	up(&priv->sem);
+}
+
 static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
 					    int missed_count)
 {
@@ -4456,6 +4526,14 @@ static void ipw_rx_queue_replenish(void 
 	ipw_rx_queue_restock(priv);
 }
 
+static void ipw_bg_rx_queue_replenish(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_rx_queue_replenish(data);
+	up(&priv->sem);
+}
+
 /* Assumes that the skb field of the buffers in 'pool' is kept accurate.
  * If an SKB has been detached, the POOL needs to have it's SKB set to NULL
  * This free routine walks the list of POOL entries and if SKB is set to
@@ -4715,6 +4793,215 @@ struct ipw_network_match {
 	struct ipw_supported_rates rates;
 };
 
+static int ipw_find_adhoc_network(struct ipw_priv *priv,
+				  struct ipw_network_match *match,
+				  struct ieee80211_network *network,
+				  int roaming)
+{
+	struct ipw_supported_rates rates;
+
+	/* Verify that this network's capability is compatible with the
+	 * current mode (AdHoc or Infrastructure) */
+	if ((priv->ieee->iw_mode == IW_MODE_ADHOC &&
+	     !(network->capability & WLAN_CAPABILITY_IBSS))) {
+		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded due to "
+				"capability mismatch.\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid));
+		return 0;
+	}
+
+	/* If we do not have an ESSID for this AP, we can not associate with
+	 * it */
+	if (network->flags & NETWORK_EMPTY_ESSID) {
+		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+				"because of hidden ESSID.\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid));
+		return 0;
+	}
+
+	if (unlikely(roaming)) {
+		/* If we are roaming, then ensure check if this is a valid
+		 * network to try and roam to */
+		if ((network->ssid_len != match->network->ssid_len) ||
+		    memcmp(network->ssid, match->network->ssid,
+			   network->ssid_len)) {
+			IPW_DEBUG_MERGE("Netowrk '%s (" MAC_FMT ")' excluded "
+					"because of non-network ESSID.\n",
+					escape_essid(network->ssid,
+						     network->ssid_len),
+					MAC_ARG(network->bssid));
+			return 0;
+		}
+	} else {
+		/* If an ESSID has been configured then compare the broadcast
+		 * ESSID to ours */
+		if ((priv->config & CFG_STATIC_ESSID) &&
+		    ((network->ssid_len != priv->essid_len) ||
+		     memcmp(network->ssid, priv->essid,
+			    min(network->ssid_len, priv->essid_len)))) {
+			char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
+			strncpy(escaped,
+				escape_essid(network->ssid, network->ssid_len),
+				sizeof(escaped));
+			IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+					"because of ESSID mismatch: '%s'.\n",
+					escaped, MAC_ARG(network->bssid),
+					escape_essid(priv->essid,
+						     priv->essid_len));
+			return 0;
+		}
+	}
+
+	/* If the old network rate is better than this one, don't bother
+	 * testing everything else. */
+
+	if (network->time_stamp[0] < match->network->time_stamp[0]) {
+		IPW_DEBUG_MERGE
+		    ("Network '%s excluded because newer than current network.\n",
+		     escape_essid(match->network->ssid,
+				  match->network->ssid_len));
+		return 0;
+	} else if (network->time_stamp[1] < match->network->time_stamp[1]) {
+		IPW_DEBUG_MERGE
+		    ("Network '%s excluded because newer than current network.\n",
+		     escape_essid(match->network->ssid,
+				  match->network->ssid_len));
+		return 0;
+	}
+
+	/* Now go through and see if the requested network is valid... */
+	if (priv->ieee->scan_age != 0 &&
+	    time_after(jiffies, network->last_scanned + priv->ieee->scan_age)) {
+		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+				"because of age: %lums.\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid),
+				(jiffies - network->last_scanned) / (HZ / 100));
+		return 0;
+	}
+
+	if ((priv->config & CFG_STATIC_CHANNEL) &&
+	    (network->channel != priv->channel)) {
+		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+				"because of channel mismatch: %d != %d.\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid),
+				network->channel, priv->channel);
+		return 0;
+	}
+
+	/* Verify privacy compatability */
+	if (((priv->capability & CAP_PRIVACY_ON) ? 1 : 0) !=
+	    ((network->capability & WLAN_CAPABILITY_PRIVACY) ? 1 : 0)) {
+		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+				"because of privacy mismatch: %s != %s.\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid),
+				priv->capability & CAP_PRIVACY_ON ? "on" :
+				"off",
+				network->capability &
+				WLAN_CAPABILITY_PRIVACY ? "on" : "off");
+		return 0;
+	}
+
+	if (!memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
+		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+				"because of the same BSSID match: " MAC_FMT
+				".\n", escape_essid(network->ssid,
+						    network->ssid_len),
+				MAC_ARG(network->bssid), MAC_ARG(priv->bssid));
+		return 0;
+	}
+
+	/* Filter out any incompatible freq / mode combinations */
+	if (!ieee80211_is_valid_mode(priv->ieee, network->mode)) {
+		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+				"because of invalid frequency/mode "
+				"combination.\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid));
+		return 0;
+	}
+
+	/* Ensure that the rates supported by the driver are compatible with
+	 * this AP, including verification of basic rates (mandatory) */
+	if (!ipw_compatible_rates(priv, network, &rates)) {
+		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+				"because configured rate mask excludes "
+				"AP mandatory rate.\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid));
+		return 0;
+	}
+
+	if (rates.num_rates == 0) {
+		IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' excluded "
+				"because of no compatible rates.\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid));
+		return 0;
+	}
+
+	/* TODO: Perform any further minimal comparititive tests.  We do not
+	 * want to put too much policy logic here; intelligent scan selection
+	 * should occur within a generic IEEE 802.11 user space tool.  */
+
+	/* Set up 'new' AP to this network */
+	ipw_copy_rates(&match->rates, &rates);
+	match->network = network;
+	IPW_DEBUG_MERGE("Network '%s (" MAC_FMT ")' is a viable match.\n",
+			escape_essid(network->ssid, network->ssid_len),
+			MAC_ARG(network->bssid));
+
+	return 1;
+}
+
+static void ipw_merge_adhoc_network(void *data)
+{
+	struct ipw_priv *priv = data;
+	struct ieee80211_network *network = NULL;
+	struct ipw_network_match match = {
+		.network = priv->assoc_network
+	};
+
+	if ((priv->status & STATUS_ASSOCIATED)
+	    && (priv->ieee->iw_mode == IW_MODE_ADHOC)) {
+		/* First pass through ROAM process -- look for a better
+		 * network */
+		unsigned long flags;
+
+		spin_lock_irqsave(&priv->ieee->lock, flags);
+		list_for_each_entry(network, &priv->ieee->network_list, list) {
+			if (network != priv->assoc_network)
+				ipw_find_adhoc_network(priv, &match, network,
+						       1);
+		}
+		spin_unlock_irqrestore(&priv->ieee->lock, flags);
+
+		if (match.network == priv->assoc_network) {
+			IPW_DEBUG_MERGE("No better ADHOC in this network to "
+					"merge to.\n");
+			return;
+		}
+
+		down(&priv->sem);
+		if ((priv->ieee->iw_mode == IW_MODE_ADHOC)) {
+			IPW_DEBUG_MERGE("remove network %s\n",
+					escape_essid(priv->essid,
+						     priv->essid_len));
+			ipw_remove_current_network(priv);
+		}
+
+		ipw_disassociate(priv);
+		priv->assoc_network = match.network;
+		up(&priv->sem);
+		return;
+	}
+
+}
+
 static int ipw_best_network(struct ipw_priv *priv,
 			    struct ipw_network_match *match,
 			    struct ieee80211_network *network, int roaming)
@@ -4997,6 +5284,14 @@ static void ipw_adhoc_check(void *data)
 			   priv->assoc_request.beacon_interval);
 }
 
+static void ipw_bg_adhoc_check(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_adhoc_check(data);
+	up(&priv->sem);
+}
+
 #ifdef CONFIG_IPW_DEBUG
 static void ipw_debug_config(struct ipw_priv *priv)
 {
@@ -5181,10 +5476,9 @@ static int ipw_request_scan(struct ipw_p
 		/* If we are roaming, then make this a directed scan for the current
 		 * network.  Otherwise, ensure that every other scan is a fast
 		 * channel hop scan */
-		if ((priv->status & STATUS_ROAMING)
-		    || (!(priv->status & STATUS_ASSOCIATED)
-			&& (priv->config & CFG_STATIC_ESSID)
-			&& (le32_to_cpu(scan.full_scan_index) % 2))) {
+		if ((priv->status & STATUS_ROAMING) || (!(priv->status & STATUS_ASSOCIATED) && (priv->config & CFG_STATIC_ESSID) && (le32_to_cpu(scan.full_scan_index) % 2))) {	/* || (
+																						   (priv->status & STATUS_ASSOCIATED) &&
+																						   (priv->ieee->iw_mode == IW_MODE_ADHOC))) { */
 			err = ipw_send_ssid(priv, priv->essid, priv->essid_len);
 			if (err) {
 				IPW_DEBUG_HC
@@ -5257,6 +5551,22 @@ static int ipw_request_scan(struct ipw_p
 	return 0;
 }
 
+static void ipw_bg_request_scan(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_request_scan(data);
+	up(&priv->sem);
+}
+
+static void ipw_bg_abort_scan(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_abort_scan(data);
+	up(&priv->sem);
+}
+
 /* Support for wpa_supplicant. Will be replaced with WEXT once
  * they get WPA support. */
 
@@ -5473,8 +5783,7 @@ void ipw_wpa_assoc_frame(struct ipw_priv
 	/* make sure WPA is enabled */
 	ipw_wpa_enable(priv, 1);
 
-	if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))
-		ipw_disassociate(priv);
+	ipw_disassociate(priv);
 }
 
 static int ipw_wpa_set_wpa_ie(struct net_device *dev,
@@ -5830,6 +6139,12 @@ static int ipw_associate_network(struct 
 		priv->sys_config.dot11g_auto_detection = 1;
 	else
 		priv->sys_config.dot11g_auto_detection = 0;
+
+	if (priv->ieee->iw_mode == IW_MODE_ADHOC)
+		priv->sys_config.answer_broadcast_ssid_probe = 1;
+	else
+		priv->sys_config.answer_broadcast_ssid_probe = 0;
+
 	err = ipw_send_system_config(priv, &priv->sys_config);
 	if (err) {
 		IPW_DEBUG_HC("Attempt to send sys config command failed.\n");
@@ -5933,7 +6248,15 @@ static void ipw_roam(void *data)
 	priv->status &= ~STATUS_ROAMING;
 }
 
-static void ipw_associate(void *data)
+static void ipw_bg_roam(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_roam(data);
+	up(&priv->sem);
+}
+
+static int ipw_associate(void *data)
 {
 	struct ipw_priv *priv = data;
 
@@ -5945,11 +6268,23 @@ static void ipw_associate(void *data)
 	struct list_head *element;
 	unsigned long flags;
 
+	if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
+		IPW_DEBUG_ASSOC
+		    ("Not attempting association (already in progress)\n");
+		return 0;
+	}
+
+	if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
+		IPW_DEBUG_ASSOC
+		    ("Not attempting association (scanning or not initialized)\n");
+		return 0;
+	}
+
 	if (!(priv->config & CFG_ASSOCIATE) &&
 	    !(priv->config & (CFG_STATIC_ESSID |
 			      CFG_STATIC_CHANNEL | CFG_STATIC_BSSID))) {
 		IPW_DEBUG_ASSOC("Not attempting association (associate=0)\n");
-		return;
+		return 0;
 	}
 
 	/* Protect our use of the network_list */
@@ -5984,10 +6319,20 @@ static void ipw_associate(void *data)
 			queue_delayed_work(priv->workqueue, &priv->request_scan,
 					   SCAN_INTERVAL);
 
-		return;
+		return 0;
 	}
 
 	ipw_associate_network(priv, network, rates, 0);
+
+	return 1;
+}
+
+static void ipw_bg_associate(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_associate(data);
+	up(&priv->sem);
 }
 
 static inline void ipw_handle_data_packet(struct ipw_priv *priv,
@@ -6037,6 +6382,10 @@ static inline int is_network_packet(stru
 	 * this network, discarding packets coming from ourselves */
 	switch (priv->ieee->iw_mode) {
 	case IW_MODE_ADHOC:	/* Header: Dest. | Source    | BSSID */
+		/* packets from our adapter are dropped (echo) */
+		if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
+			return 0;
+
 		/* {broad,multi}cast packets to our IBSS go through */
 		if (is_broadcast_ether_addr(header->addr1) ||
 		    is_multicast_ether_addr(header->addr1))
@@ -6045,9 +6394,12 @@ static inline int is_network_packet(stru
 		/* packets to our adapter go through */
 		return !memcmp(header->addr1, priv->net_dev->dev_addr,
 			       ETH_ALEN);
-		break;
 
 	case IW_MODE_INFRA:	/* Header: Dest. | AP{BSSID} | Source */
+		/* packets from our adapter are dropped (echo) */
+		if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
+			return 0;
+
 		/* {broad,multi}cast packets to our IBSS go through */
 		if (is_broadcast_ether_addr(header->addr1) ||
 		    is_multicast_ether_addr(header->addr1))
@@ -6056,7 +6408,6 @@ static inline int is_network_packet(stru
 		/* packets to our adapter go through */
 		return !memcmp(header->addr1, priv->net_dev->dev_addr,
 			       ETH_ALEN);
-		break;
 	}
 
 	return 1;
@@ -6101,9 +6452,13 @@ static void ipw_rx(struct ipw_priv *priv
 		switch (pkt->header.message_type) {
 		case RX_FRAME_TYPE:	/* 802.11 frame */  {
 				struct ieee80211_rx_stats stats = {
-					.rssi = pkt->u.frame.rssi_dbm -
+					.rssi =
+					    le16_to_cpu(pkt->u.frame.rssi_dbm) -
 					    IPW_RSSI_TO_DBM,
-					/* .signal = le16_to_cpu(pkt->u.frame.signal), */
+					.signal =
+					    le16_to_cpu(pkt->u.frame.signal),
+					.noise =
+					    le16_to_cpu(pkt->u.frame.noise),
 					.rate = pkt->u.frame.rate,
 					.mac_time = jiffies,
 					.received_channel =
@@ -6120,6 +6475,8 @@ static void ipw_rx(struct ipw_priv *priv
 					stats.mask |= IEEE80211_STATMASK_RSSI;
 				if (stats.signal != 0)
 					stats.mask |= IEEE80211_STATMASK_SIGNAL;
+				if (stats.noise != 0)
+					stats.mask |= IEEE80211_STATMASK_NOISE;
 				if (stats.rate != 0)
 					stats.mask |= IEEE80211_STATMASK_RATE;
 
@@ -6179,11 +6536,34 @@ static void ipw_rx(struct ipw_priv *priv
 					     ||
 					     (WLAN_FC_GET_STYPE
 					      (le16_to_cpu(header->frame_ctl))
-					      == IEEE80211_STYPE_BEACON))
-					    && !memcmp(header->addr3,
-						       priv->bssid, ETH_ALEN))
-						ipw_add_station(priv,
-								header->addr2);
+					      == IEEE80211_STYPE_BEACON))) {
+						if (!memcmp
+						    (header->addr3, priv->bssid,
+						     ETH_ALEN))
+							ipw_add_station(priv,
+									header->
+									addr2);
+						else {
+							struct
+							    ieee80211_probe_response
+							*beacon;
+							beacon =
+							    (struct
+							     ieee80211_probe_response
+							     *)header;
+							if (le16_to_cpu
+							    (beacon->
+							     capability) &
+							    WLAN_CAPABILITY_IBSS)
+							{
+								queue_work
+								    (priv->
+								     workqueue,
+								     &priv->
+								     merge_networks);
+							}
+						}
+					}
 					break;
 
 				case IEEE80211_FTYPE_CTL:
@@ -6262,14 +6642,16 @@ static int ipw_wx_get_name(struct net_de
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	if (priv->status & STATUS_RF_KILL_MASK) {
+	down(&priv->sem);
+	if (priv->status & STATUS_RF_KILL_MASK)
 		strcpy(wrqu->name, "radio off");
-	} else if (!(priv->status & STATUS_ASSOCIATED))
+	else if (!(priv->status & STATUS_ASSOCIATED))
 		strcpy(wrqu->name, "unassociated");
 	else
 		snprintf(wrqu->name, IFNAMSIZ, "IEEE 802.11%c",
 			 ipw_modes[priv->assoc_request.ieee_mode]);
 	IPW_DEBUG_WX("Name: %s\n", wrqu->name);
+	up(&priv->sem);
 	return 0;
 }
 
@@ -6278,13 +6660,9 @@ static int ipw_set_channel(struct ipw_pr
 	if (channel == 0) {
 		IPW_DEBUG_INFO("Setting channel to ANY (0)\n");
 		priv->config &= ~CFG_STATIC_CHANNEL;
-		if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED |
-				      STATUS_ASSOCIATING))) {
-			IPW_DEBUG_ASSOC("Attempting to associate with new "
-					"parameters.\n");
-			ipw_associate(priv);
-		}
-
+		IPW_DEBUG_ASSOC("Attempting to associate with new "
+				"parameters.\n");
+		ipw_associate(priv);
 		return 0;
 	}
 
@@ -6299,12 +6677,9 @@ static int ipw_set_channel(struct ipw_pr
 	IPW_DEBUG_INFO("Setting channel to %i\n", (int)channel);
 	priv->channel = channel;
 
-	/* If we are currently associated, or trying to associate
-	 * then see if this is a new channel (causing us to disassociate) */
-	if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
-		IPW_DEBUG_ASSOC("Disassociating due to channel change.\n");
-		ipw_disassociate(priv);
-	} else if (!(priv->status & (STATUS_SCANNING)))
+	/* Network configuration changed -- force [re]association */
+	IPW_DEBUG_ASSOC("[re]association triggered due to channel change.\n");
+	if (!ipw_disassociate(priv))
 		ipw_associate(priv);
 
 	return 0;
@@ -6316,6 +6691,7 @@ static int ipw_wx_set_freq(struct net_de
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct iw_freq *fwrq = &wrqu->freq;
+	int ret = 0;
 
 	/* if setting by freq convert to channel */
 	if (fwrq->e == 1) {
@@ -6337,7 +6713,10 @@ static int ipw_wx_set_freq(struct net_de
 		return -EOPNOTSUPP;
 
 	IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
-	return ipw_set_channel(priv, (u8) fwrq->m);
+	down(&priv->sem);
+	ret = ipw_set_channel(priv, (u8) fwrq->m);
+	up(&priv->sem);
+	return ret;
 }
 
 static int ipw_wx_get_freq(struct net_device *dev,
@@ -6350,12 +6729,14 @@ static int ipw_wx_get_freq(struct net_de
 
 	/* If we are associated, trying to associate, or have a statically
 	 * configured CHANNEL then return that; otherwise return ANY */
+	down(&priv->sem);
 	if (priv->config & CFG_STATIC_CHANNEL ||
 	    priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))
 		wrqu->freq.m = priv->channel;
 	else
 		wrqu->freq.m = 0;
 
+	up(&priv->sem);
 	IPW_DEBUG_WX("GET Freq/Channel -> %d \n", priv->channel);
 	return 0;
 }
@@ -6368,9 +6749,11 @@ static int ipw_wx_set_mode(struct net_de
 	int err = 0;
 
 	IPW_DEBUG_WX("Set MODE: %d\n", wrqu->mode);
-
-	if (wrqu->mode == priv->ieee->iw_mode)
+	down(&priv->sem);
+	if (wrqu->mode == priv->ieee->iw_mode) {
+		up(&priv->sem);
 		return 0;
+	}
 
 	switch (wrqu->mode) {
 #ifdef CONFIG_IPW_MONITOR
@@ -6383,6 +6766,7 @@ static int ipw_wx_set_mode(struct net_de
 		wrqu->mode = IW_MODE_INFRA;
 		break;
 	default:
+		up(&priv->sem);
 		return -EINVAL;
 	}
 
@@ -6407,8 +6791,9 @@ static int ipw_wx_set_mode(struct net_de
 #endif
 
 	priv->ieee->iw_mode = wrqu->mode;
-	queue_work(priv->workqueue, &priv->adapter_restart);
 
+	queue_work(priv->workqueue, &priv->adapter_restart);
+	up(&priv->sem);
 	return err;
 }
 
@@ -6417,10 +6802,10 @@ static int ipw_wx_get_mode(struct net_de
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-
+	down(&priv->sem);
 	wrqu->mode = priv->ieee->iw_mode;
 	IPW_DEBUG_WX("Get MODE -> %d\n", wrqu->mode);
-
+	up(&priv->sem);
 	return 0;
 }
 
@@ -6466,7 +6851,7 @@ static int ipw_wx_get_range(struct net_d
 	range->max_qual.qual = 100;
 	/* TODO: Find real max RSSI and stick here */
 	range->max_qual.level = 0;
-	range->max_qual.noise = 0;
+	range->max_qual.noise = priv->ieee->worst_rssi + 0x100;
 	range->max_qual.updated = 7;	/* Updated all three */
 
 	range->avg_qual.qual = 70;
@@ -6474,7 +6859,7 @@ static int ipw_wx_get_range(struct net_d
 	range->avg_qual.level = 0;	/* FIXME to real average level */
 	range->avg_qual.noise = 0;
 	range->avg_qual.updated = 7;	/* Updated all three */
-
+	down(&priv->sem);
 	range->num_bitrates = min(priv->rates.num_rates, (u8) IW_MAX_BITRATES);
 
 	for (i = 0; i < range->num_bitrates; i++)
@@ -6507,7 +6892,7 @@ static int ipw_wx_get_range(struct net_d
 			break;
 	}
 	range->num_frequency = val;
-
+	up(&priv->sem);
 	IPW_DEBUG_WX("GET Range\n");
 	return 0;
 }
@@ -6527,25 +6912,23 @@ static int ipw_wx_set_wap(struct net_dev
 
 	if (wrqu->ap_addr.sa_family != ARPHRD_ETHER)
 		return -EINVAL;
-
+	down(&priv->sem);
 	if (!memcmp(any, wrqu->ap_addr.sa_data, ETH_ALEN) ||
 	    !memcmp(off, wrqu->ap_addr.sa_data, ETH_ALEN)) {
 		/* we disable mandatory BSSID association */
 		IPW_DEBUG_WX("Setting AP BSSID to ANY\n");
 		priv->config &= ~CFG_STATIC_BSSID;
-		if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED |
-				      STATUS_ASSOCIATING))) {
-			IPW_DEBUG_ASSOC("Attempting to associate with new "
-					"parameters.\n");
-			ipw_associate(priv);
-		}
-
+		IPW_DEBUG_ASSOC("Attempting to associate with new "
+				"parameters.\n");
+		ipw_associate(priv);
+		up(&priv->sem);
 		return 0;
 	}
 
 	priv->config |= CFG_STATIC_BSSID;
 	if (!memcmp(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN)) {
 		IPW_DEBUG_WX("BSSID set to current BSSID.\n");
+		up(&priv->sem);
 		return 0;
 	}
 
@@ -6554,14 +6937,12 @@ static int ipw_wx_set_wap(struct net_dev
 
 	memcpy(priv->bssid, wrqu->ap_addr.sa_data, ETH_ALEN);
 
-	/* If we are currently associated, or trying to associate
-	 * then see if this is a new BSSID (causing us to disassociate) */
-	if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
-		IPW_DEBUG_ASSOC("Disassociating due to BSSID change.\n");
-		ipw_disassociate(priv);
-	} else if (!(priv->status & (STATUS_SCANNING)))
+	/* Network configuration changed -- force [re]association */
+	IPW_DEBUG_ASSOC("[re]association triggered due to BSSID change.\n");
+	if (!ipw_disassociate(priv))
 		ipw_associate(priv);
 
+	up(&priv->sem);
 	return 0;
 }
 
@@ -6572,6 +6953,7 @@ static int ipw_wx_get_wap(struct net_dev
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	/* If we are associated, trying to associate, or have a statically
 	 * configured BSSID then return that; otherwise return ANY */
+	down(&priv->sem);
 	if (priv->config & CFG_STATIC_BSSID ||
 	    priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
 		wrqu->ap_addr.sa_family = ARPHRD_ETHER;
@@ -6581,6 +6963,7 @@ static int ipw_wx_get_wap(struct net_dev
 
 	IPW_DEBUG_WX("Getting WAP BSSID: " MAC_FMT "\n",
 		     MAC_ARG(wrqu->ap_addr.sa_data));
+	up(&priv->sem);
 	return 0;
 }
 
@@ -6591,7 +6974,7 @@ static int ipw_wx_set_essid(struct net_d
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	char *essid = "";	/* ANY */
 	int length = 0;
-
+	down(&priv->sem);
 	if (wrqu->essid.flags && wrqu->essid.length) {
 		length = wrqu->essid.length - 1;
 		essid = extra;
@@ -6599,13 +6982,12 @@ static int ipw_wx_set_essid(struct net_d
 	if (length == 0) {
 		IPW_DEBUG_WX("Setting ESSID to ANY\n");
 		priv->config &= ~CFG_STATIC_ESSID;
-		if (!(priv->status & (STATUS_SCANNING | STATUS_ASSOCIATED |
-				      STATUS_ASSOCIATING))) {
+		if (!(priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
 			IPW_DEBUG_ASSOC("Attempting to associate with new "
 					"parameters.\n");
 			ipw_associate(priv);
 		}
-
+		up(&priv->sem);
 		return 0;
 	}
 
@@ -6615,6 +6997,7 @@ static int ipw_wx_set_essid(struct net_d
 
 	if (priv->essid_len == length && !memcmp(priv->essid, extra, length)) {
 		IPW_DEBUG_WX("ESSID set to current ESSID.\n");
+		up(&priv->sem);
 		return 0;
 	}
 
@@ -6624,14 +7007,12 @@ static int ipw_wx_set_essid(struct net_d
 	priv->essid_len = length;
 	memcpy(priv->essid, essid, priv->essid_len);
 
-	/* If we are currently associated, or trying to associate
-	 * then see if this is a new ESSID (causing us to disassociate) */
-	if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
-		IPW_DEBUG_ASSOC("Disassociating due to ESSID change.\n");
-		ipw_disassociate(priv);
-	} else if (!(priv->status & (STATUS_SCANNING)))
+	/* Network configuration changed -- force [re]association */
+	IPW_DEBUG_ASSOC("[re]association triggered due to ESSID change.\n");
+	if (!ipw_disassociate(priv))
 		ipw_associate(priv);
 
+	up(&priv->sem);
 	return 0;
 }
 
@@ -6643,6 +7024,7 @@ static int ipw_wx_get_essid(struct net_d
 
 	/* If we are associated, trying to associate, or have a statically
 	 * configured ESSID then return that; otherwise return ANY */
+	down(&priv->sem);
 	if (priv->config & CFG_STATIC_ESSID ||
 	    priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
 		IPW_DEBUG_WX("Getting essid: '%s'\n",
@@ -6655,7 +7037,7 @@ static int ipw_wx_get_essid(struct net_d
 		wrqu->essid.length = 0;
 		wrqu->essid.flags = 0;	/* active */
 	}
-
+	up(&priv->sem);
 	return 0;
 }
 
@@ -6668,11 +7050,12 @@ static int ipw_wx_set_nick(struct net_de
 	IPW_DEBUG_WX("Setting nick to '%s'\n", extra);
 	if (wrqu->data.length > IW_ESSID_MAX_SIZE)
 		return -E2BIG;
-
+	down(&priv->sem);
 	wrqu->data.length = min((size_t) wrqu->data.length, sizeof(priv->nick));
 	memset(priv->nick, 0, sizeof(priv->nick));
 	memcpy(priv->nick, extra, wrqu->data.length);
 	IPW_DEBUG_TRACE("<<\n");
+	up(&priv->sem);
 	return 0;
 
 }
@@ -6683,9 +7066,11 @@ static int ipw_wx_get_nick(struct net_de
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	IPW_DEBUG_WX("Getting nick\n");
+	down(&priv->sem);
 	wrqu->data.length = strlen(priv->nick) + 1;
 	memcpy(extra, priv->nick, wrqu->data.length);
 	wrqu->data.flags = 1;	/* active */
+	up(&priv->sem);
 	return 0;
 }
 
@@ -6778,25 +7163,26 @@ static int ipw_wx_set_rate(struct net_de
       apply:
 	IPW_DEBUG_WX("Setting rate mask to 0x%08X [%s]\n",
 		     mask, fixed ? "fixed" : "sub-rates");
-
+	down(&priv->sem);
 	if (mask == IEEE80211_DEFAULT_RATES_MASK)
 		priv->config &= ~CFG_FIXED_RATE;
 	else
 		priv->config |= CFG_FIXED_RATE;
 
-	if (priv->rates_mask != mask) {
-		priv->rates_mask = mask;
-		/* If we are already associated or are currently trying to
-		 * associate, disassociate and try again */
-		if ((priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING))) {
-			IPW_DEBUG_ASSOC("Disassociating due to RATE change.\n");
-			ipw_disassociate(priv);
-		} else if (!(priv->status & (STATUS_SCANNING))) {
-			/* We are not yet associated, so kick one off... */
-			ipw_associate(priv);
-		}
+	if (priv->rates_mask == mask) {
+		IPW_DEBUG_WX("Mask set to current mask.\n");
+		up(&priv->sem);
+		return 0;
 	}
 
+	priv->rates_mask = mask;
+
+	/* Network configuration changed -- force [re]association */
+	IPW_DEBUG_ASSOC("[re]association triggered due to rates change.\n");
+	if (!ipw_disassociate(priv))
+		ipw_associate(priv);
+
+	up(&priv->sem);
 	return 0;
 }
 
@@ -6805,8 +7191,9 @@ static int ipw_wx_get_rate(struct net_de
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
+	down(&priv->sem);
 	wrqu->bitrate.value = priv->last_rate;
-
+	up(&priv->sem);
 	IPW_DEBUG_WX("GET Rate -> %d \n", wrqu->bitrate.value);
 	return 0;
 }
@@ -6816,18 +7203,20 @@ static int ipw_wx_set_rts(struct net_dev
 			  union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-
+	down(&priv->sem);
 	if (wrqu->rts.disabled)
 		priv->rts_threshold = DEFAULT_RTS_THRESHOLD;
 	else {
 		if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
-		    wrqu->rts.value > MAX_RTS_THRESHOLD)
+		    wrqu->rts.value > MAX_RTS_THRESHOLD) {
+			up(&priv->sem);
 			return -EINVAL;
-
+		}
 		priv->rts_threshold = wrqu->rts.value;
 	}
 
 	ipw_send_rts_threshold(priv, priv->rts_threshold);
+	up(&priv->sem);
 	IPW_DEBUG_WX("SET RTS Threshold -> %d \n", priv->rts_threshold);
 	return 0;
 }
@@ -6837,10 +7226,11 @@ static int ipw_wx_get_rts(struct net_dev
 			  union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
+	down(&priv->sem);
 	wrqu->rts.value = priv->rts_threshold;
 	wrqu->rts.fixed = 0;	/* no auto select */
 	wrqu->rts.disabled = (wrqu->rts.value == DEFAULT_RTS_THRESHOLD);
-
+	up(&priv->sem);
 	IPW_DEBUG_WX("GET RTS Threshold -> %d \n", wrqu->rts.value);
 	return 0;
 }
@@ -6852,15 +7242,21 @@ static int ipw_wx_set_txpow(struct net_d
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ipw_tx_power tx_power;
 	int i;
-
-	if (ipw_radio_kill_sw(priv, wrqu->power.disabled))
+	down(&priv->sem);
+	if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
+		up(&priv->sem);
 		return -EINPROGRESS;
+	}
 
-	if (wrqu->power.flags != IW_TXPOW_DBM)
+	if (wrqu->power.flags != IW_TXPOW_DBM) {
+		up(&priv->sem);
 		return -EINVAL;
+	}
 
-	if ((wrqu->power.value > 20) || (wrqu->power.value < -12))
+	if ((wrqu->power.value > 20) || (wrqu->power.value < -12)) {
+		up(&priv->sem);
 		return -EINVAL;
+	}
 
 	priv->tx_power = wrqu->power.value;
 
@@ -6881,9 +7277,11 @@ static int ipw_wx_set_txpow(struct net_d
 	if (ipw_send_tx_power(priv, &tx_power))
 		goto error;
 
+	up(&priv->sem);
 	return 0;
 
       error:
+	up(&priv->sem);
 	return -EIO;
 }
 
@@ -6892,11 +7290,12 @@ static int ipw_wx_get_txpow(struct net_d
 			    union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-
+	down(&priv->sem);
 	wrqu->power.value = priv->tx_power;
 	wrqu->power.fixed = 1;
 	wrqu->power.flags = IW_TXPOW_DBM;
 	wrqu->power.disabled = (priv->status & STATUS_RF_KILL_MASK) ? 1 : 0;
+	up(&priv->sem);
 
 	IPW_DEBUG_WX("GET TX Power -> %s %d \n",
 		     wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value);
@@ -6909,7 +7308,7 @@ static int ipw_wx_set_frag(struct net_de
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-
+	down(&priv->sem);
 	if (wrqu->frag.disabled)
 		priv->ieee->fts = DEFAULT_FTS;
 	else {
@@ -6921,6 +7320,7 @@ static int ipw_wx_set_frag(struct net_de
 	}
 
 	ipw_send_frag_threshold(priv, wrqu->frag.value);
+	up(&priv->sem);
 	IPW_DEBUG_WX("SET Frag Threshold -> %d \n", wrqu->frag.value);
 	return 0;
 }
@@ -6930,10 +7330,11 @@ static int ipw_wx_get_frag(struct net_de
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
+	down(&priv->sem);
 	wrqu->frag.value = priv->ieee->fts;
 	wrqu->frag.fixed = 0;	/* no auto select */
 	wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FTS);
-
+	up(&priv->sem);
 	IPW_DEBUG_WX("GET Frag Threshold -> %d \n", wrqu->frag.value);
 
 	return 0;
@@ -6961,8 +7362,12 @@ static int ipw_wx_set_scan(struct net_de
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	IPW_DEBUG_WX("Start scan\n");
-	if (ipw_request_scan(priv))
+	down(&priv->sem);
+	if (ipw_request_scan(priv)) {
+		up(&priv->sem);
 		return -EIO;
+	}
+	up(&priv->sem);
 	return 0;
 }
 
@@ -6996,16 +7401,17 @@ static int ipw_wx_set_power(struct net_d
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int err;
-
+	down(&priv->sem);
 	if (wrqu->power.disabled) {
 		priv->power_mode = IPW_POWER_LEVEL(priv->power_mode);
 		err = ipw_send_power_mode(priv, IPW_POWER_MODE_CAM);
 		if (err) {
 			IPW_DEBUG_WX("failed setting power mode.\n");
+			up(&priv->sem);
 			return err;
 		}
 		IPW_DEBUG_WX("SET Power Management Mode -> off\n");
-
+		up(&priv->sem);
 		return 0;
 	}
 
@@ -7017,6 +7423,7 @@ static int ipw_wx_set_power(struct net_d
 	default:		/* Otherwise we don't support it */
 		IPW_DEBUG_WX("SET PM Mode: %X not supported.\n",
 			     wrqu->power.flags);
+		up(&priv->sem);
 		return -EOPNOTSUPP;
 	}
 
@@ -7029,11 +7436,12 @@ static int ipw_wx_set_power(struct net_d
 	err = ipw_send_power_mode(priv, IPW_POWER_LEVEL(priv->power_mode));
 	if (err) {
 		IPW_DEBUG_WX("failed setting power mode.\n");
+		up(&priv->sem);
 		return err;
 	}
 
 	IPW_DEBUG_WX("SET Power Management Mode -> 0x%02X\n", priv->power_mode);
-
+	up(&priv->sem);
 	return 0;
 }
 
@@ -7042,12 +7450,13 @@ static int ipw_wx_get_power(struct net_d
 			    union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-
+	down(&priv->sem);
 	if (!(priv->power_mode & IPW_POWER_ENABLED))
 		wrqu->power.disabled = 1;
 	else
 		wrqu->power.disabled = 0;
 
+	up(&priv->sem);
 	IPW_DEBUG_WX("GET Power Management Mode -> %02X\n", priv->power_mode);
 
 	return 0;
@@ -7060,7 +7469,7 @@ static int ipw_wx_set_powermode(struct n
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int mode = *(int *)extra;
 	int err;
-
+	down(&priv->sem);
 	if ((mode < 1) || (mode > IPW_POWER_LIMIT)) {
 		mode = IPW_POWER_AC;
 		priv->power_mode = mode;
@@ -7073,10 +7482,11 @@ static int ipw_wx_set_powermode(struct n
 
 		if (err) {
 			IPW_DEBUG_WX("failed setting power mode.\n");
+			up(&priv->sem);
 			return err;
 		}
 	}
-
+	up(&priv->sem);
 	return 0;
 }
 
@@ -7125,7 +7535,7 @@ static int ipw_wx_set_wireless_mode(stru
 		IPW_WARNING("Attempt to set invalid wireless mode: %d\n", mode);
 		return -EINVAL;
 	}
-
+	down(&priv->sem);
 	if (priv->adapter == IPW_2915ABG) {
 		priv->ieee->abg_true = 1;
 		if (mode & IEEE_A) {
@@ -7137,6 +7547,7 @@ static int ipw_wx_set_wireless_mode(stru
 		if (mode & IEEE_A) {
 			IPW_WARNING("Attempt to set 2200BG into "
 				    "802.11a mode\n");
+			up(&priv->sem);
 			return -EINVAL;
 		}
 
@@ -7160,16 +7571,12 @@ static int ipw_wx_set_wireless_mode(stru
 	priv->ieee->modulation = modulation;
 	init_supported_rates(priv, &priv->rates);
 
-	/* If we are currently associated, or trying to associate
-	 * then see if this is a new configuration (causing us to
-	 * disassociate) */
-	if (priv->status & (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
-		/* The resulting association will trigger
-		 * the new rates to be sent to the device */
-		IPW_DEBUG_ASSOC("Disassociating due to mode change.\n");
-		ipw_disassociate(priv);
-	} else
+	/* Network configuration changed -- force [re]association */
+	IPW_DEBUG_ASSOC("[re]association triggered due to mode change.\n");
+	if (!ipw_disassociate(priv)) {
 		ipw_send_supported_rates(priv, &priv->rates);
+		ipw_associate(priv);
+	}
 
 	/* Update the band LEDs */
 	ipw_led_band_on(priv);
@@ -7177,6 +7584,7 @@ static int ipw_wx_set_wireless_mode(stru
 	IPW_DEBUG_WX("PRIV SET MODE: %c%c%c\n",
 		     mode & IEEE_A ? 'a' : '.',
 		     mode & IEEE_B ? 'b' : '.', mode & IEEE_G ? 'g' : '.');
+	up(&priv->sem);
 	return 0;
 }
 
@@ -7185,7 +7593,7 @@ static int ipw_wx_get_wireless_mode(stru
 				    union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-
+	down(&priv->sem);
 	switch (priv->ieee->mode) {
 	case IEEE_A:
 		strncpy(extra, "802.11a (1)", MAX_WX_STRING);
@@ -7216,6 +7624,7 @@ static int ipw_wx_get_wireless_mode(stru
 	IPW_DEBUG_WX("PRIV GET MODE: %s\n", extra);
 
 	wrqu->data.length = strlen(extra) + 1;
+	up(&priv->sem);
 
 	return 0;
 }
@@ -7226,18 +7635,17 @@ static int ipw_wx_set_preamble(struct ne
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int mode = *(int *)extra;
-
+	down(&priv->sem);
 	/* Switching from SHORT -> LONG requires a disassociation */
 	if (mode == 1) {
 		if (!(priv->config & CFG_PREAMBLE_LONG)) {
 			priv->config |= CFG_PREAMBLE_LONG;
-			if (priv->status &
-			    (STATUS_ASSOCIATED | STATUS_ASSOCIATING)) {
-				IPW_DEBUG_ASSOC
-				    ("Disassociating due to preamble "
-				     "change.\n");
-				ipw_disassociate(priv);
-			}
+
+			/* Network configuration changed -- force [re]association */
+			IPW_DEBUG_ASSOC
+			    ("[re]association triggered due to preamble change.\n");
+			if (!ipw_disassociate(priv))
+				ipw_associate(priv);
 		}
 		goto done;
 	}
@@ -7246,10 +7654,11 @@ static int ipw_wx_set_preamble(struct ne
 		priv->config &= ~CFG_PREAMBLE_LONG;
 		goto done;
 	}
-
+	up(&priv->sem);
 	return -EINVAL;
 
       done:
+	up(&priv->sem);
 	return 0;
 }
 
@@ -7258,12 +7667,12 @@ static int ipw_wx_get_preamble(struct ne
 			       union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-
+	down(&priv->sem);
 	if (priv->config & CFG_PREAMBLE_LONG)
 		snprintf(wrqu->name, IFNAMSIZ, "long (1)");
 	else
 		snprintf(wrqu->name, IFNAMSIZ, "auto (0)");
-
+	up(&priv->sem);
 	return 0;
 }
 
@@ -7275,7 +7684,7 @@ static int ipw_wx_set_monitor(struct net
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int *parms = (int *)extra;
 	int enable = (parms[0] > 0);
-
+	down(&priv->sem);
 	IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
 	if (enable) {
 		if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
@@ -7285,11 +7694,14 @@ static int ipw_wx_set_monitor(struct net
 
 		ipw_set_channel(priv, parms[1]);
 	} else {
-		if (priv->ieee->iw_mode != IW_MODE_MONITOR)
+		if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
+			up(&priv->sem);
 			return 0;
+		}
 		priv->net_dev->type = ARPHRD_ETHER;
 		queue_work(priv->workqueue, &priv->adapter_restart);
 	}
+	up(&priv->sem);
 	return 0;
 }
 
@@ -7473,7 +7885,7 @@ static inline void init_sys_config(struc
 	sys_config->dot11g_auto_detection = 0;
 	sys_config->enable_cts_to_self = 0;
 	sys_config->bt_coexist_collision_thr = 0;
-	sys_config->pass_noise_stats_to_host = 0;	//1 -- fix for 256
+	sys_config->pass_noise_stats_to_host = 1;	//1 -- fix for 256
 }
 
 static int ipw_net_open(struct net_device *dev)
@@ -7481,9 +7893,11 @@ static int ipw_net_open(struct net_devic
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	IPW_DEBUG_INFO("dev->open\n");
 	/* we should be verifying the device is ready to be opened */
+	down(&priv->sem);
 	if (!(priv->status & STATUS_RF_KILL_MASK) &&
 	    (priv->status & STATUS_ASSOCIATED))
 		netif_start_queue(dev);
+	up(&priv->sem);
 	return 0;
 }
 
@@ -7511,6 +7925,7 @@ static inline void ipw_tx_skb(struct ipw
 	struct clx2_queue *q = &txq->q;
 	u8 id, hdr_len, unicast;
 	u16 remaining_bytes;
+	int fc;
 
 	switch (priv->ieee->iw_mode) {
 	case IW_MODE_ADHOC:
@@ -7562,6 +7977,9 @@ static inline void ipw_tx_skb(struct ipw
 	if (priv->assoc_request.preamble_length == DCT_FLAG_SHORT_PREAMBLE)
 		tfd->u.data.tx_flags |= DCT_FLAG_SHORT_PREAMBLE;
 
+	fc = le16_to_cpu(hdr->frame_ctl);
+	hdr->frame_ctl = cpu_to_le16(fc & ~IEEE80211_FCTL_MOREFRAGS);
+
 	memcpy(&tfd->u.data.tfd.tfd_24.mchdr, hdr, hdr_len);
 
 	/* payload */
@@ -7644,7 +8062,6 @@ static int ipw_net_hard_start_xmit(struc
 	unsigned long flags;
 
 	IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
-
 	spin_lock_irqsave(&priv->lock, flags);
 
 	if (!(priv->status & STATUS_ASSOCIATED)) {
@@ -7655,13 +8072,15 @@ static int ipw_net_hard_start_xmit(struc
 	}
 
 	ipw_tx_skb(priv, txb);
+	spin_unlock_irqrestore(&priv->lock, flags);
 	ipw_led_activity_on(priv);
 
-	spin_unlock_irqrestore(&priv->lock, flags);
+//      up(&priv->sem);
 	return 0;
 
       fail_unlock:
 	spin_unlock_irqrestore(&priv->lock, flags);
+//      up(&priv->sem);
 	return 1;
 }
 
@@ -7685,11 +8104,13 @@ static int ipw_net_set_mac_address(struc
 	struct sockaddr *addr = p;
 	if (!is_valid_ether_addr(addr->sa_data))
 		return -EADDRNOTAVAIL;
+	down(&priv->sem);
 	priv->config |= CFG_CUSTOM_MAC;
 	memcpy(priv->mac_addr, addr->sa_data, ETH_ALEN);
 	printk(KERN_INFO "%s: Setting MAC to " MAC_FMT "\n",
 	       priv->net_dev->name, MAC_ARG(priv->mac_addr));
 	queue_work(priv->workqueue, &priv->adapter_restart);
+	up(&priv->sem);
 	return 0;
 }
 
@@ -7733,8 +8154,9 @@ static int ipw_ethtool_get_eeprom(struct
 
 	if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
 		return -EINVAL;
-
+	down(&p->sem);
 	memcpy(bytes, &((u8 *) p->eeprom)[eeprom->offset], eeprom->len);
+	up(&p->sem);
 	return 0;
 }
 
@@ -7746,12 +8168,12 @@ static int ipw_ethtool_set_eeprom(struct
 
 	if (eeprom->offset + eeprom->len > CX2_EEPROM_IMAGE_SIZE)
 		return -EINVAL;
-
+	down(&p->sem);
 	memcpy(&((u8 *) p->eeprom)[eeprom->offset], bytes, eeprom->len);
 	for (i = IPW_EEPROM_DATA;
 	     i < IPW_EEPROM_DATA + CX2_EEPROM_IMAGE_SIZE; i++)
 		ipw_write8(p, i, p->eeprom[i]);
-
+	up(&p->sem);
 	return 0;
 }
 
@@ -7775,6 +8197,8 @@ static irqreturn_t ipw_isr(int irq, void
 
 	if (!(priv->status & STATUS_INT_ENABLED)) {
 		/* Shared IRQ */
+//              ipw_write32(priv, CX2_INTA_RW, CX2_INTA_MASK_ALL);
+//              return IRQ_HANDLED;
 		goto none;
 	}
 
@@ -7843,6 +8267,14 @@ static void ipw_rf_kill(void *adapter)
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
+static void ipw_bg_rf_kill(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_rf_kill(data);
+	up(&priv->sem);
+}
+
 void ipw_link_up(struct ipw_priv *priv)
 {
 	netif_carrier_on(priv->net_dev);
@@ -7854,6 +8286,7 @@ void ipw_link_up(struct ipw_priv *priv)
 		netif_start_queue(priv->net_dev);
 	}
 
+	cancel_delayed_work(&priv->request_scan);
 	ipw_reset_stats(priv);
 	/* Ensure the rate is updated immediately */
 	priv->last_rate = ipw_get_current_rate(priv);
@@ -7865,6 +8298,14 @@ void ipw_link_up(struct ipw_priv *priv)
 		queue_delayed_work(priv->workqueue, &priv->request_scan, HZ);
 }
 
+static void ipw_bg_link_up(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_link_up(data);
+	up(&priv->sem);
+}
+
 void ipw_link_down(struct ipw_priv *priv)
 {
 	ipw_led_link_down(priv);
@@ -7883,6 +8324,14 @@ void ipw_link_down(struct ipw_priv *priv
 	queue_work(priv->workqueue, &priv->request_scan);
 }
 
+static void ipw_bg_link_down(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_link_down(data);
+	up(&priv->sem);
+}
+
 static int ipw_setup_deferred_work(struct ipw_priv *priv)
 {
 	int ret = 0;
@@ -7890,28 +8339,31 @@ static int ipw_setup_deferred_work(struc
 	priv->workqueue = create_workqueue(DRV_NAME);
 	init_waitqueue_head(&priv->wait_command_queue);
 
-	INIT_WORK(&priv->adhoc_check, ipw_adhoc_check, priv);
-	INIT_WORK(&priv->associate, ipw_associate, priv);
-	INIT_WORK(&priv->disassociate, ipw_disassociate, priv);
-	INIT_WORK(&priv->rx_replenish, ipw_rx_queue_replenish, priv);
-	INIT_WORK(&priv->adapter_restart, ipw_adapter_restart, priv);
-	INIT_WORK(&priv->rf_kill, ipw_rf_kill, priv);
-	INIT_WORK(&priv->up, (void (*)(void *))ipw_up, priv);
-	INIT_WORK(&priv->down, (void (*)(void *))ipw_down, priv);
+	INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
+	INIT_WORK(&priv->associate, ipw_bg_associate, priv);
+	INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
+	INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
+	INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
+	INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
+	INIT_WORK(&priv->up, (void (*)(void *))ipw_bg_up, priv);
+	INIT_WORK(&priv->down, (void (*)(void *))ipw_bg_down, priv);
 	INIT_WORK(&priv->request_scan,
-		  (void (*)(void *))ipw_request_scan, priv);
+		  (void (*)(void *))ipw_bg_request_scan, priv);
 	INIT_WORK(&priv->gather_stats,
-		  (void (*)(void *))ipw_gather_stats, priv);
-	INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_abort_scan, priv);
-	INIT_WORK(&priv->roam, ipw_roam, priv);
-	INIT_WORK(&priv->scan_check, ipw_scan_check, priv);
-	INIT_WORK(&priv->link_up, (void (*)(void *))ipw_link_up, priv);
-	INIT_WORK(&priv->link_down, (void (*)(void *))ipw_link_down, priv);
-	INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_led_link_on, priv);
-	INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_led_link_off,
+		  (void (*)(void *))ipw_bg_gather_stats, priv);
+	INIT_WORK(&priv->abort_scan, (void (*)(void *))ipw_bg_abort_scan, priv);
+	INIT_WORK(&priv->roam, ipw_bg_roam, priv);
+	INIT_WORK(&priv->scan_check, ipw_bg_scan_check, priv);
+	INIT_WORK(&priv->link_up, (void (*)(void *))ipw_bg_link_up, priv);
+	INIT_WORK(&priv->link_down, (void (*)(void *))ipw_bg_link_down, priv);
+	INIT_WORK(&priv->led_link_on, (void (*)(void *))ipw_bg_led_link_on,
+		  priv);
+	INIT_WORK(&priv->led_link_off, (void (*)(void *))ipw_bg_led_link_off,
 		  priv);
-	INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_led_activity_off,
+	INIT_WORK(&priv->led_act_off, (void (*)(void *))ipw_bg_led_activity_off,
 		  priv);
+	INIT_WORK(&priv->merge_networks,
+		  (void (*)(void *))ipw_merge_adhoc_network, priv);
 
 	tasklet_init(&priv->irq_tasklet, (void (*)(unsigned long))
 		     ipw_irq_tasklet, (unsigned long)priv);
@@ -7924,7 +8376,7 @@ static void shim__set_security(struct ne
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int i;
-
+	down(&priv->sem);
 	for (i = 0; i < 4; i++) {
 		if (sec->flags & (1 << i)) {
 			priv->sec.key_sizes[i] = sec->key_sizes[i];
@@ -7989,6 +8441,7 @@ static void shim__set_security(struct ne
 		ipw_disassociate(priv);
 	}
 #endif
+	up(&priv->sem);
 }
 
 static int init_supported_rates(struct ipw_priv *priv,
@@ -8054,6 +8507,11 @@ static int ipw_config(struct ipw_priv *p
 
 	/* set basic system config settings */
 	init_sys_config(&priv->sys_config);
+	if (priv->ieee->iw_mode == IW_MODE_ADHOC)
+		priv->sys_config.answer_broadcast_ssid_probe = 1;
+	else
+		priv->sys_config.answer_broadcast_ssid_probe = 0;
+
 	if (ipw_send_system_config(priv, &priv->sys_config))
 		goto error;
 
@@ -8075,8 +8533,10 @@ static int ipw_config(struct ipw_priv *p
 		goto error;
 
 	/* If configured to try and auto-associate, kick off a scan */
-	if ((priv->config & CFG_ASSOCIATE) && ipw_request_scan(priv))
+	if ((priv->config & CFG_ASSOCIATE) && ipw_request_scan(priv)) {
+		IPW_WARNING("error sending scan request\n");
 		goto error;
+	}
 
 	return 0;
 
@@ -8106,8 +8566,9 @@ static int ipw_up(struct ipw_priv *priv)
 			eeprom_parse_mac(priv, priv->mac_addr);
 		memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
 
-		if (priv->status & STATUS_RF_KILL_MASK)
+		if (priv->status & STATUS_RF_KILL_MASK) {
 			return 0;
+		}
 
 		rc = ipw_config(priv);
 		if (!rc) {
@@ -8115,12 +8576,11 @@ static int ipw_up(struct ipw_priv *priv)
 			ipw_led_init(priv);
 			ipw_led_radio_on(priv);
 			priv->notif_missed_beacons = 0;
+			priv->status |= STATUS_INIT;
 			return 0;
-		} else {
-			IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n",
-				       rc);
 		}
 
+		IPW_DEBUG_INFO("Device configuration failed: 0x%08X\n", rc);
 		IPW_DEBUG_INFO("Failed to config device on retry %d of %d\n",
 			       i, MAX_HW_RESTARTS);
 
@@ -8132,13 +8592,22 @@ static int ipw_up(struct ipw_priv *priv)
 	/* tried to restart and config the device for as long as our
 	 * patience could withstand */
 	IPW_ERROR("Unable to initialize device after %d attempts.\n", i);
+
 	return -EIO;
 }
 
+static void ipw_bg_up(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_up(data);
+	up(&priv->sem);
+}
+
 static void ipw_down(struct ipw_priv *priv)
 {
-	/* Attempt to disable the card */
 #if 0
+	/* Attempt to disable the card */
 	ipw_send_card_disable(priv, 0);
 #endif
 
@@ -8147,7 +8616,6 @@ static void ipw_down(struct ipw_priv *pr
 
 	/* Clear all bits but the RF Kill */
 	priv->status &= STATUS_RF_KILL_MASK;
-
 	netif_carrier_off(priv->net_dev);
 	netif_stop_queue(priv->net_dev);
 
@@ -8156,6 +8624,14 @@ static void ipw_down(struct ipw_priv *pr
 	ipw_led_radio_off(priv);
 }
 
+static void ipw_bg_down(void *data)
+{
+	struct ipw_priv *priv = data;
+	down(&priv->sem);
+	ipw_down(data);
+	up(&priv->sem);
+}
+
 static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct iwreq *wrq = (struct iwreq *)rq;
@@ -8176,21 +8652,26 @@ static int ipw_ioctl(struct net_device *
 static int ipw_net_init(struct net_device *dev)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-
+	down(&priv->sem);
 	if (priv->status & STATUS_RF_KILL_SW) {
 		IPW_WARNING("Radio disabled by module parameter.\n");
+		up(&priv->sem);
 		return 0;
 	} else if (rf_kill_active(priv)) {
 		IPW_WARNING("Radio Frequency Kill Switch is On:\n"
 			    "Kill switch must be turned off for "
 			    "wireless networking to work.\n");
 		queue_delayed_work(priv->workqueue, &priv->rf_kill, 2 * HZ);
+		up(&priv->sem);
 		return 0;
 	}
 
-	if (ipw_up(priv))
+	if (ipw_up(priv)) {
+		up(&priv->sem);
 		return -EIO;
+	}
 
+	up(&priv->sem);
 	return 0;
 }
 
@@ -8275,6 +8756,7 @@ static int ipw_pci_probe(struct pci_dev 
 #endif
 	spin_lock_init(&priv->lock);
 
+	init_MUTEX(&priv->sem);
 	if (pci_enable_device(pdev)) {
 		err = -ENODEV;
 		goto out_free_ieee80211;
@@ -8416,9 +8898,14 @@ static int ipw_pci_probe(struct pci_dev 
 	ipw_wx_data.spy_data = &priv->ieee->spy_data;
 	ipw_wx_data.ieee80211 = priv->ieee;
 
+	down(&priv->sem);
+
 	priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
 	priv->ieee->set_security = shim__set_security;
 
+	priv->ieee->perfect_rssi = -20;
+	priv->ieee->worst_rssi = -85;
+
 	net_dev->open = ipw_net_open;
 	net_dev->stop = ipw_net_stop;
 	net_dev->init = ipw_net_init;
@@ -8438,15 +8925,16 @@ static int ipw_pci_probe(struct pci_dev 
 	err = sysfs_create_group(&pdev->dev.kobj, &ipw_attribute_group);
 	if (err) {
 		IPW_ERROR("failed to create sysfs device attributes\n");
+		up(&priv->sem);
 		goto out_release_irq;
 	}
 
+	up(&priv->sem);
 	err = register_netdev(net_dev);
 	if (err) {
 		IPW_ERROR("failed to register network device\n");
 		goto out_remove_sysfs;
 	}
-
 	return 0;
 
       out_remove_sysfs:
@@ -8623,8 +9111,7 @@ module_param(auto_create, int, 0444);
 MODULE_PARM_DESC(auto_create, "auto create adhoc network (default on)");
 
 module_param(led, int, 0444);
-MODULE_PARM_DESC(auto_create,
-		 "enable led control on some systems (default 0 off)\n");
+MODULE_PARM_DESC(led, "enable led control on some systems (default 0 off)\n");
 
 module_param(debug, int, 0444);
 MODULE_PARM_DESC(debug, "debug output mask");
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 1b339cb..243b8ea 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -936,8 +936,8 @@ struct ipw_priv {
 	struct ieee80211_device *ieee;
 	struct ieee80211_security sec;
 
-	/* spinlock */
 	spinlock_t lock;
+	struct semaphore sem;
 
 	/* basic pci-network driver stuff */
 	struct pci_dev *pci_dev;
@@ -1068,6 +1068,7 @@ struct ipw_priv {
 	struct work_struct led_link_on;
 	struct work_struct led_link_off;
 	struct work_struct led_act_off;
+	struct work_struct merge_networks;
 
 #define IPW_2200BG  1
 #define IPW_2915ABG 2
@@ -1160,6 +1161,7 @@ do { if (ipw_debug_level & (level)) \
 #define IPW_DL_TRACE         (1<<28)
 
 #define IPW_DL_STATS         (1<<29)
+#define IPW_DL_MERGE         (1<<30)
 
 #define IPW_ERROR(f, a...) printk(KERN_ERR DRV_NAME ": " f, ## a)
 #define IPW_WARNING(f, a...) printk(KERN_WARNING DRV_NAME ": " f, ## a)
@@ -1187,6 +1189,7 @@ do { if (ipw_debug_level & (level)) \
 #define IPW_DEBUG_STATE(f, a...) IPW_DEBUG(IPW_DL_STATE | IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
 #define IPW_DEBUG_ASSOC(f, a...) IPW_DEBUG(IPW_DL_ASSOC | IPW_DL_INFO, f, ## a)
 #define IPW_DEBUG_STATS(f, a...) IPW_DEBUG(IPW_DL_STATS, f, ## a)
+#define IPW_DEBUG_MERGE(f, a...) IPW_DEBUG(IPW_DL_MERGE, f, ## a)
 
 #include <linux/ctype.h>
 
---
0.99.8.GIT


--- NEW FILE 2915-Catch-ipw2200-up-to-equivelancy-with-v1.0.4.txt ---
Subject: [PATCH] Catch ipw2200 up to equivelancy with v1.0.4
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124939082 -0500

* Fixed #627 problem with open APs not working with wpa_supplicant
* Fixed #632 problem with 'txpower auto' setting power incorrectly (thanks
  to Kai Groner)
* Fixed #634 problem with 'iwconfig eth1 frag 0' hanging the shell
* Fixed problem with adapter not fully powering off during suspend to RAM or
  when module unloaded.
* Fixed #645 problem with turning fixed rates off not taking effect until
  you reload the driver
* Fixed problem with firmware restart if wpa_supplicant was used to set a key
  that wasn't exactly 5 or 13 bytes in length.
* Fixed #623 Added iwpriv sw_reset extension to reset sw parameters
* Added managment frame export to user space with frame statistics
* Fixed #652 Modified the driver to load the EEPROM data even if RF KILL is
  active during driver load
* Global s:CX2_:IPW_:g to make code more consistent
* Fixed #572 problem with setting txpower to auto
* Fixed #656 problem with kernel oops if mode auto; modprobe -r ipw2200
* Added QoS (CONFIG_IPW_QOS) support.  This is being actively developed but
  is the first step in getting WMM support into the driver and the kernel.
* Fixed some race conditions with channel changes, association, and scan
  abort that could periodically cause a firmware restart.
* Added some extensions to export scan and network statistics to user space
  (exposed through speed_scan and net_stats sysfs entries)
* Fixed a few bugs in how monitor mode was supported (scan lists
  weren't quite right)
* Updated the firmware requirement from 2.2 to 2.3 which supports
  monitor mode.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c | 2620 +++++++++++++++++++++++++++++-----------
 drivers/net/wireless/ipw2200.h |  475 +++++--
 2 files changed, 2194 insertions(+), 901 deletions(-)

applies-to: e9d3e4b02fa9404f7a9633d98e3a35468eb516be
b095c3819805f87d73d41641a53e4c070360d783
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 0bf1931..0a583af 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -32,11 +32,13 @@
 
 #include "ipw2200.h"
 
-#define IPW2200_VERSION "1.0.3"
+#define IPW2200_VERSION "1.0.4"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2004 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
 
+#define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
+
 MODULE_DESCRIPTION(DRV_DESCRIPTION);
 MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
@@ -51,10 +53,78 @@ static int associate = 1;
 static int auto_create = 1;
 static int led = 0;
 static int disable = 0;
+static int hwcrypto = 1;
 static const char ipw_modes[] = {
 	'a', 'b', 'g', '?'
 };
 
+#ifdef CONFIG_IPW_QOS
+static int qos_enable = 0;
+static int qos_burst_enable = 0;
+static int qos_no_ack_mask = 0;
+static int burst_duration_CCK = 0;
+static int burst_duration_OFDM = 0;
+
+static struct ieee80211_qos_parameters def_qos_parameters_OFDM = {
+	{QOS_TX0_CW_MIN_OFDM, QOS_TX1_CW_MIN_OFDM, QOS_TX2_CW_MIN_OFDM,
+	 QOS_TX3_CW_MIN_OFDM},
+	{QOS_TX0_CW_MAX_OFDM, QOS_TX1_CW_MAX_OFDM, QOS_TX2_CW_MAX_OFDM,
+	 QOS_TX3_CW_MAX_OFDM},
+	{QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
+	{QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
+	{QOS_TX0_TXOP_LIMIT_OFDM, QOS_TX1_TXOP_LIMIT_OFDM,
+	 QOS_TX2_TXOP_LIMIT_OFDM, QOS_TX3_TXOP_LIMIT_OFDM}
+};
+
+static struct ieee80211_qos_parameters def_qos_parameters_CCK = {
+	{QOS_TX0_CW_MIN_CCK, QOS_TX1_CW_MIN_CCK, QOS_TX2_CW_MIN_CCK,
+	 QOS_TX3_CW_MIN_CCK},
+	{QOS_TX0_CW_MAX_CCK, QOS_TX1_CW_MAX_CCK, QOS_TX2_CW_MAX_CCK,
+	 QOS_TX3_CW_MAX_CCK},
+	{QOS_TX0_AIFS, QOS_TX1_AIFS, QOS_TX2_AIFS, QOS_TX3_AIFS},
+	{QOS_TX0_ACM, QOS_TX1_ACM, QOS_TX2_ACM, QOS_TX3_ACM},
+	{QOS_TX0_TXOP_LIMIT_CCK, QOS_TX1_TXOP_LIMIT_CCK, QOS_TX2_TXOP_LIMIT_CCK,
+	 QOS_TX3_TXOP_LIMIT_CCK}
+};
+
+static struct ieee80211_qos_parameters def_parameters_OFDM = {
+	{DEF_TX0_CW_MIN_OFDM, DEF_TX1_CW_MIN_OFDM, DEF_TX2_CW_MIN_OFDM,
+	 DEF_TX3_CW_MIN_OFDM},
+	{DEF_TX0_CW_MAX_OFDM, DEF_TX1_CW_MAX_OFDM, DEF_TX2_CW_MAX_OFDM,
+	 DEF_TX3_CW_MAX_OFDM},
+	{DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
+	{DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
+	{DEF_TX0_TXOP_LIMIT_OFDM, DEF_TX1_TXOP_LIMIT_OFDM,
+	 DEF_TX2_TXOP_LIMIT_OFDM, DEF_TX3_TXOP_LIMIT_OFDM}
+};
+
+static struct ieee80211_qos_parameters def_parameters_CCK = {
+	{DEF_TX0_CW_MIN_CCK, DEF_TX1_CW_MIN_CCK, DEF_TX2_CW_MIN_CCK,
+	 DEF_TX3_CW_MIN_CCK},
+	{DEF_TX0_CW_MAX_CCK, DEF_TX1_CW_MAX_CCK, DEF_TX2_CW_MAX_CCK,
+	 DEF_TX3_CW_MAX_CCK},
+	{DEF_TX0_AIFS, DEF_TX1_AIFS, DEF_TX2_AIFS, DEF_TX3_AIFS},
+	{DEF_TX0_ACM, DEF_TX1_ACM, DEF_TX2_ACM, DEF_TX3_ACM},
+	{DEF_TX0_TXOP_LIMIT_CCK, DEF_TX1_TXOP_LIMIT_CCK, DEF_TX2_TXOP_LIMIT_CCK,
+	 DEF_TX3_TXOP_LIMIT_CCK}
+};
+
+static u8 qos_oui[QOS_OUI_LEN] = { 0x00, 0x50, 0xF2 };
+
+static int from_priority_to_tx_queue[] = {
+	IPW_TX_QUEUE_1, IPW_TX_QUEUE_2, IPW_TX_QUEUE_2, IPW_TX_QUEUE_1,
+	IPW_TX_QUEUE_3, IPW_TX_QUEUE_3, IPW_TX_QUEUE_4, IPW_TX_QUEUE_4
+};
+
+static u32 ipw_qos_get_burst_duration(struct ipw_priv *priv);
+
+static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
+				       *qos_param);
+static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
+				     *qos_param);
+#endif				/* CONFIG_IPW_QOS */
+
+static void ipw_remove_current_network(struct ipw_priv *priv);
 static void ipw_rx(struct ipw_priv *priv);
 static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
 				struct clx2_tx_queue *txq, int qindex);
@@ -75,33 +145,8 @@ static void ipw_bg_down(void *);
 static int ipw_config(struct ipw_priv *);
 static int init_supported_rates(struct ipw_priv *priv,
 				struct ipw_supported_rates *prates);
-
-static u8 band_b_active_channel[MAX_B_CHANNELS] = {
-	1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 0
-};
-static u8 band_a_active_channel[MAX_A_CHANNELS] = {
-	36, 40, 44, 48, 149, 153, 157, 161, 165, 52, 56, 60, 64, 0
-};
-
-static int is_valid_channel(int mode_mask, int channel)
-{
-	int i;
-
-	if (!channel)
-		return 0;
-
-	if (mode_mask & IEEE_A)
-		for (i = 0; i < MAX_A_CHANNELS; i++)
-			if (band_a_active_channel[i] == channel)
-				return IEEE_A;
-
-	if (mode_mask & (IEEE_B | IEEE_G))
-		for (i = 0; i < MAX_B_CHANNELS; i++)
-			if (band_b_active_channel[i] == channel)
-				return mode_mask & (IEEE_B | IEEE_G);
-
-	return 0;
-}
+static void ipw_set_hwcrypto_keys(struct ipw_priv *);
+static void ipw_send_wep_keys(struct ipw_priv *, int);
 
 static char *snprint_line(char *buf, size_t count,
 			  const u8 * data, u32 len, u32 ofs)
@@ -241,24 +286,24 @@ static void _ipw_write_indirect(struct i
 static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
 {
 	IPW_DEBUG_IO(" %p : reg = 0x%8X : value = 0x%8X\n", priv, reg, value);
-	_ipw_write32(priv, CX2_INDIRECT_ADDR, reg);
-	_ipw_write32(priv, CX2_INDIRECT_DATA, value);
+	_ipw_write32(priv, IPW_INDIRECT_ADDR, reg);
+	_ipw_write32(priv, IPW_INDIRECT_DATA, value);
 }
 
 static void _ipw_write_reg8(struct ipw_priv *priv, u32 reg, u8 value)
 {
 	IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
-	_ipw_write32(priv, CX2_INDIRECT_ADDR, reg & CX2_INDIRECT_ADDR_MASK);
-	_ipw_write8(priv, CX2_INDIRECT_DATA, value);
+	_ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
+	_ipw_write8(priv, IPW_INDIRECT_DATA, value);
 	IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
-		     (unsigned long)(priv->hw_base + CX2_INDIRECT_DATA), value);
+		     (unsigned long)(priv->hw_base + IPW_INDIRECT_DATA), value);
 }
 
 static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
[...4452 lines suppressed...]
-#define IPW_EEPROM_DATA_SRAM_ADDRESS (CX2_SHARED_LOWER_BOUND + 0x814)
-#define IPW_EEPROM_DATA_SRAM_SIZE    (CX2_SHARED_LOWER_BOUND + 0x818)
-#define IPW_EEPROM_LOAD_DISABLE      (CX2_SHARED_LOWER_BOUND + 0x81C)
-#define IPW_EEPROM_DATA              (CX2_SHARED_LOWER_BOUND + 0x820)
-#define IPW_EEPROM_UPPER_ADDRESS     (CX2_SHARED_LOWER_BOUND + 0x9E0)
-
-#define IPW_STATION_TABLE_LOWER      (CX2_SHARED_LOWER_BOUND + 0xA0C)
-#define IPW_STATION_TABLE_UPPER      (CX2_SHARED_LOWER_BOUND + 0xB0C)
-#define IPW_REQUEST_ATIM             (CX2_SHARED_LOWER_BOUND + 0xB0C)
-#define IPW_ATIM_SENT                (CX2_SHARED_LOWER_BOUND + 0xB10)
-#define IPW_WHO_IS_AWAKE             (CX2_SHARED_LOWER_BOUND + 0xB14)
-#define IPW_DURING_ATIM_WINDOW       (CX2_SHARED_LOWER_BOUND + 0xB18)
+#define IPW_EEPROM_DATA_SRAM_ADDRESS (IPW_SHARED_LOWER_BOUND + 0x814)
+#define IPW_EEPROM_DATA_SRAM_SIZE    (IPW_SHARED_LOWER_BOUND + 0x818)
+#define IPW_EEPROM_LOAD_DISABLE      (IPW_SHARED_LOWER_BOUND + 0x81C)
+#define IPW_EEPROM_DATA              (IPW_SHARED_LOWER_BOUND + 0x820)
+#define IPW_EEPROM_UPPER_ADDRESS     (IPW_SHARED_LOWER_BOUND + 0x9E0)
+
+#define IPW_STATION_TABLE_LOWER      (IPW_SHARED_LOWER_BOUND + 0xA0C)
+#define IPW_STATION_TABLE_UPPER      (IPW_SHARED_LOWER_BOUND + 0xB0C)
+#define IPW_REQUEST_ATIM             (IPW_SHARED_LOWER_BOUND + 0xB0C)
+#define IPW_ATIM_SENT                (IPW_SHARED_LOWER_BOUND + 0xB10)
+#define IPW_WHO_IS_AWAKE             (IPW_SHARED_LOWER_BOUND + 0xB14)
+#define IPW_DURING_ATIM_WINDOW       (IPW_SHARED_LOWER_BOUND + 0xB18)
 
 #define MSB                             1
 #define LSB                             0
@@ -1367,7 +1519,7 @@ do { if (ipw_debug_level & (level)) \
 
 #define FW_MEM_REG_LOWER_BOUND          0x00300000
 #define FW_MEM_REG_EEPROM_ACCESS        (FW_MEM_REG_LOWER_BOUND + 0x40)
-#define CX2_EVENT_REG                   (FW_MEM_REG_LOWER_BOUND + 0x04)
+#define IPW_EVENT_REG                   (FW_MEM_REG_LOWER_BOUND + 0x04)
 #define EEPROM_BIT_SK                   (1<<0)
 #define EEPROM_BIT_CS                   (1<<1)
 #define EEPROM_BIT_DI                   (1<<2)
@@ -1376,50 +1528,47 @@ do { if (ipw_debug_level & (level)) \
 #define EEPROM_CMD_READ                 0x2
 
 /* Interrupts masks */
-#define CX2_INTA_NONE   0x00000000
+#define IPW_INTA_NONE   0x00000000
 
-#define CX2_INTA_BIT_RX_TRANSFER                   0x00000002
-#define CX2_INTA_BIT_STATUS_CHANGE                 0x00000010
-#define CX2_INTA_BIT_BEACON_PERIOD_EXPIRED         0x00000020
+#define IPW_INTA_BIT_RX_TRANSFER                   0x00000002
+#define IPW_INTA_BIT_STATUS_CHANGE                 0x00000010
+#define IPW_INTA_BIT_BEACON_PERIOD_EXPIRED         0x00000020
 
 //Inta Bits for CF
-#define CX2_INTA_BIT_TX_CMD_QUEUE                  0x00000800
-#define CX2_INTA_BIT_TX_QUEUE_1                    0x00001000
-#define CX2_INTA_BIT_TX_QUEUE_2                    0x00002000
-#define CX2_INTA_BIT_TX_QUEUE_3                    0x00004000
-#define CX2_INTA_BIT_TX_QUEUE_4                    0x00008000
-
-#define CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE      0x00010000
-
-#define CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN        0x00100000
-#define CX2_INTA_BIT_POWER_DOWN                    0x00200000
-
-#define CX2_INTA_BIT_FW_INITIALIZATION_DONE        0x01000000
-#define CX2_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE  0x02000000
-#define CX2_INTA_BIT_RF_KILL_DONE                  0x04000000
-#define CX2_INTA_BIT_FATAL_ERROR             0x40000000
-#define CX2_INTA_BIT_PARITY_ERROR            0x80000000
+#define IPW_INTA_BIT_TX_CMD_QUEUE                  0x00000800
+#define IPW_INTA_BIT_TX_QUEUE_1                    0x00001000
+#define IPW_INTA_BIT_TX_QUEUE_2                    0x00002000
+#define IPW_INTA_BIT_TX_QUEUE_3                    0x00004000
+#define IPW_INTA_BIT_TX_QUEUE_4                    0x00008000
+
+#define IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE      0x00010000
+
+#define IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN        0x00100000
+#define IPW_INTA_BIT_POWER_DOWN                    0x00200000
+
+#define IPW_INTA_BIT_FW_INITIALIZATION_DONE        0x01000000
+#define IPW_INTA_BIT_FW_CARD_DISABLE_PHY_OFF_DONE  0x02000000
+#define IPW_INTA_BIT_RF_KILL_DONE                  0x04000000
+#define IPW_INTA_BIT_FATAL_ERROR             0x40000000
+#define IPW_INTA_BIT_PARITY_ERROR            0x80000000
 
 /* Interrupts enabled at init time. */
-#define CX2_INTA_MASK_ALL                        \
-        (CX2_INTA_BIT_TX_QUEUE_1               | \
-	 CX2_INTA_BIT_TX_QUEUE_2               | \
-	 CX2_INTA_BIT_TX_QUEUE_3               | \
-	 CX2_INTA_BIT_TX_QUEUE_4               | \
-	 CX2_INTA_BIT_TX_CMD_QUEUE             | \
-	 CX2_INTA_BIT_RX_TRANSFER              | \
-	 CX2_INTA_BIT_FATAL_ERROR              | \
-	 CX2_INTA_BIT_PARITY_ERROR             | \
-	 CX2_INTA_BIT_STATUS_CHANGE            | \
-	 CX2_INTA_BIT_FW_INITIALIZATION_DONE   | \
-	 CX2_INTA_BIT_BEACON_PERIOD_EXPIRED    | \
-	 CX2_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \
-	 CX2_INTA_BIT_PREPARE_FOR_POWER_DOWN   | \
-	 CX2_INTA_BIT_POWER_DOWN               | \
-         CX2_INTA_BIT_RF_KILL_DONE )
-
-#define IPWSTATUS_ERROR_LOG     (CX2_SHARED_LOWER_BOUND + 0x410)
-#define IPW_EVENT_LOG     (CX2_SHARED_LOWER_BOUND + 0x414)
+#define IPW_INTA_MASK_ALL                        \
+        (IPW_INTA_BIT_TX_QUEUE_1               | \
+	 IPW_INTA_BIT_TX_QUEUE_2               | \
+	 IPW_INTA_BIT_TX_QUEUE_3               | \
+	 IPW_INTA_BIT_TX_QUEUE_4               | \
+	 IPW_INTA_BIT_TX_CMD_QUEUE             | \
+	 IPW_INTA_BIT_RX_TRANSFER              | \
+	 IPW_INTA_BIT_FATAL_ERROR              | \
+	 IPW_INTA_BIT_PARITY_ERROR             | \
+	 IPW_INTA_BIT_STATUS_CHANGE            | \
+	 IPW_INTA_BIT_FW_INITIALIZATION_DONE   | \
+	 IPW_INTA_BIT_BEACON_PERIOD_EXPIRED    | \
+	 IPW_INTA_BIT_SLAVE_MODE_HOST_CMD_DONE | \
+	 IPW_INTA_BIT_PREPARE_FOR_POWER_DOWN   | \
+	 IPW_INTA_BIT_POWER_DOWN               | \
+         IPW_INTA_BIT_RF_KILL_DONE )
 
 /* FW event log definitions */
 #define EVENT_ELEM_SIZE     (3 * sizeof(u32))
@@ -1429,6 +1578,11 @@ do { if (ipw_debug_level & (level)) \
 #define ERROR_ELEM_SIZE     (7 * sizeof(u32))
 #define ERROR_START_OFFSET  (1 * sizeof(u32))
 
+/* TX power level (dbm) */
+#define IPW_TX_POWER_MIN	-12
+#define IPW_TX_POWER_MAX	20
+#define IPW_TX_POWER_DEFAULT	IPW_TX_POWER_MAX
+
 enum {
 	IPW_FW_ERROR_OK = 0,
 	IPW_FW_ERROR_FAIL,
@@ -1441,8 +1595,8 @@ enum {
 	IPW_FW_ERROR_ALLOC_FAIL,
 	IPW_FW_ERROR_DMA_UNDERRUN,
 	IPW_FW_ERROR_DMA_STATUS,
-	IPW_FW_ERROR_DINOSTATUS_ERROR,
-	IPW_FW_ERROR_EEPROMSTATUS_ERROR,
+	IPW_FW_ERROR_DINO_ERROR,
+	IPW_FW_ERROR_EEPROM_ERROR,
 	IPW_FW_ERROR_SYSASSERT,
 	IPW_FW_ERROR_FATAL_ERROR
 };
@@ -1458,6 +1612,8 @@ enum {
 #define HC_IBSS_RECONF    4
 #define HC_DISASSOC_QUIET 5
 
+#define HC_QOS_SUPPORT_ASSOC  0x01
+
 #define IPW_RATE_CAPABILITIES 1
 #define IPW_RATE_CONNECT      0
 
@@ -1628,18 +1784,20 @@ enum {
 	IPW_ORD_TABLE_7_LAST
 };
 
-#define IPW_ORDINALS_TABLE_LOWER        (CX2_SHARED_LOWER_BOUND + 0x500)
-#define IPW_ORDINALS_TABLE_0            (CX2_SHARED_LOWER_BOUND + 0x180)
-#define IPW_ORDINALS_TABLE_1            (CX2_SHARED_LOWER_BOUND + 0x184)
-#define IPW_ORDINALS_TABLE_2            (CX2_SHARED_LOWER_BOUND + 0x188)
-#define IPW_MEM_FIXED_OVERRIDE          (CX2_SHARED_LOWER_BOUND + 0x41C)
+#define IPWSTATUS_ERROR_LOG     (IPW_SHARED_LOWER_BOUND + 0x410)
+#define IPW_EVENT_LOG     (IPW_SHARED_LOWER_BOUND + 0x414)
+#define IPW_ORDINALS_TABLE_LOWER        (IPW_SHARED_LOWER_BOUND + 0x500)
+#define IPW_ORDINALS_TABLE_0            (IPW_SHARED_LOWER_BOUND + 0x180)
+#define IPW_ORDINALS_TABLE_1            (IPW_SHARED_LOWER_BOUND + 0x184)
+#define IPW_ORDINALS_TABLE_2            (IPW_SHARED_LOWER_BOUND + 0x188)
+#define IPW_MEM_FIXED_OVERRIDE          (IPW_SHARED_LOWER_BOUND + 0x41C)
 
 struct ipw_fixed_rate {
 	u16 tx_rates;
 	u16 reserved;
 } __attribute__ ((packed));
 
-#define CX2_INDIRECT_ADDR_MASK (~0x3ul)
+#define IPW_INDIRECT_ADDR_MASK (~0x3ul)
 
 struct host_cmd {
 	u8 cmd;
@@ -1676,15 +1834,6 @@ struct host_cmd {
 #define REG_CHANNEL_MASK            0x00003FFF
 #define IPW_IBSS_11B_DEFAULT_MASK   0x87ff
 
-static const long ipw_frequencies[] = {
-	2412, 2417, 2422, 2427,
-	2432, 2437, 2442, 2447,
-	2452, 2457, 2462, 2467,
-	2472, 2484
-};
-
-#define FREQ_COUNT ARRAY_SIZE(ipw_frequencies)
-
 #define IPW_MAX_CONFIG_RETRIES 10
 
 static inline u32 frame_hdr_len(struct ieee80211_hdr_4addr *hdr)
---
0.99.8.GIT


--- NEW FILE 2916-Catch-ipw2100-up-to-equivelancy-with-v1.1.1.txt ---
Subject: [PATCH] Catch ipw2100 up to equivelancy with v1.1.1
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124940811 -0500

* Added WE-18 support.  This allows the use of -Dext with wpa_supplicant
  > 0.4.x (thanks to Hong Liu)
* Fixed #339 problem with iwconfig set/get txpower (thanks to Hong Liu)
* Fixed #598 problem when with error messages when module loaded with
  'disable=1' (thanks to Hong Liu)
* Fixed #640 problem with 'iwlist retry' now showing min/max retry
* Fixed compatibility with wpa_supplicant and the new -Dipw interface
  (that included a fix for 64-bit compatibility)
* Added CFG_CRC_CHECK which allows passing through packets with bad
  CRCs while in monitor mode.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2100.c |  577 +++++++++++++++++++++++++++++++---------
 drivers/net/wireless/ipw2100.h |   11 -
 2 files changed, 451 insertions(+), 137 deletions(-)

applies-to: 48edc722c8445078aea620c740d19d466dd8fc25
823283549da144ff49e65c6e4a670b7784203e0b
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 449c1c0..e7c2221 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -167,12 +167,12 @@ that only one external action is invoked
 
 #include "ipw2100.h"
 
-#define IPW2100_VERSION "1.1.0"
+#define IPW2100_VERSION "1.1.1"
 
 #define DRV_NAME	"ipw2100"
 #define DRV_VERSION	IPW2100_VERSION
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2100 Network Driver"
-#define DRV_COPYRIGHT	"Copyright(c) 2003-2004 Intel Corporation"
+#define DRV_COPYRIGHT	"Copyright(c) 2003-2005 Intel Corporation"
 
 /* Debugging stuff */
 #ifdef CONFIG_IPW_DEBUG
@@ -779,7 +779,7 @@ static int ipw2100_hw_send_command(struc
 
 	if (err == 0) {
 		IPW_DEBUG_INFO("Command completion failed out after %dms.\n",
-			       HOST_COMPLETE_TIMEOUT / (HZ / 100));
+			       1000 * (HOST_COMPLETE_TIMEOUT / HZ));
 		priv->fatal_error = IPW2100_ERR_MSG_TIMEOUT;
 		priv->status &= ~STATUS_CMD_ACTIVE;
 		schedule_reset(priv);
@@ -1986,7 +1986,7 @@ static int ipw2100_set_essid(struct ipw2
 	IPW_DEBUG_HC("SSID: '%s'\n", escape_essid(essid, ssid_len));
 
 	if (ssid_len)
-		memcpy((char *)cmd.host_command_parameters, essid, ssid_len);
+		memcpy(cmd.host_command_parameters, essid, ssid_len);
 
 	if (!batch_mode) {
 		err = ipw2100_disable_adapter(priv);
@@ -2369,13 +2369,15 @@ static inline void isr_rx(struct ipw2100
 		IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
 		return;
 	}
-
+#ifdef CONFIG_IPW2100_MONITOR
 	if (unlikely(priv->ieee->iw_mode == IW_MODE_MONITOR &&
+		     priv->config & CFG_CRC_CHECK &&
 		     status->flags & IPW_STATUS_FLAG_CRC_ERROR)) {
 		IPW_DEBUG_RX("CRC error in packet.  Dropping.\n");
 		priv->ieee->stats.rx_errors++;
 		return;
 	}
+#endif
 
 	if (unlikely(priv->ieee->iw_mode != IW_MODE_MONITOR &&
 		     !(priv->status & STATUS_ASSOCIATED))) {
@@ -2744,7 +2746,6 @@ static inline int __ipw2100_tx_process(s
 			       priv->net_dev->name, txq->oldest, packet->index);
 
 		/* DATA packet; we have to unmap and free the SKB */
-		priv->ieee->stats.tx_packets++;
 		for (i = 0; i < frag_num; i++) {
 			tbd = &txq->drv[(packet->index + 1 + i) % txq->entries];
 
@@ -2757,8 +2758,6 @@ static inline int __ipw2100_tx_process(s
 					 tbd->buf_length, PCI_DMA_TODEVICE);
 		}
 
-		priv->ieee->stats.tx_bytes +=
-		    packet->info.d_struct.txb->payload_size;
 		ieee80211_txb_free(packet->info.d_struct.txb);
 		packet->info.d_struct.txb = NULL;
 
@@ -2767,13 +2766,8 @@ static inline int __ipw2100_tx_process(s
 
 		/* We have a free slot in the Tx queue, so wake up the
 		 * transmit layer if it is stopped. */
-		if (priv->status & STATUS_ASSOCIATED &&
-		    netif_queue_stopped(priv->net_dev)) {
-			IPW_DEBUG_INFO(KERN_INFO
-				       "%s: Waking net queue.\n",
-				       priv->net_dev->name);
+		if (priv->status & STATUS_ASSOCIATED)
 			netif_wake_queue(priv->net_dev);
-		}
 
 		/* A packet was processed by the hardware, so update the
 		 * watchdog */
@@ -3791,6 +3785,9 @@ static ssize_t show_ordinals(struct devi
 	u32 val_len;
 	static int loop = 0;
 
+	if (priv->status & STATUS_RF_KILL_MASK)
+		return 0;
+
 	if (loop >= sizeof(ord_data) / sizeof(*ord_data))
 		loop = 0;
 
@@ -3947,6 +3944,9 @@ static ssize_t show_bssinfo(struct devic
 	int length;
 	int ret;
 
+	if (priv->status & STATUS_RF_KILL_MASK)
+		return 0;
+
 	memset(essid, 0, sizeof(essid));
 	memset(bssid, 0, sizeof(bssid));
 
@@ -3986,8 +3986,8 @@ static ssize_t show_debug_level(struct d
 	return sprintf(buf, "0x%08X\n", ipw2100_debug_level);
 }
 
-static ssize_t store_debug_level(struct device_driver *d, const char *buf,
-				 size_t count)
+static ssize_t store_debug_level(struct device_driver *d,
+				 const char *buf, size_t count)
 {
 	char *p = (char *)buf;
 	u32 val;
@@ -4943,7 +4943,7 @@ static int ipw2100_set_mandatory_bssid(s
 #endif
 	/* if BSSID is empty then we disable mandatory bssid mode */
 	if (bssid != NULL)
-		memcpy((u8 *) cmd.host_command_parameters, bssid, ETH_ALEN);
+		memcpy(cmd.host_command_parameters, bssid, ETH_ALEN);
 
 	if (!batch_mode) {
 		err = ipw2100_disable_adapter(priv);
@@ -4959,7 +4959,6 @@ static int ipw2100_set_mandatory_bssid(s
 	return err;
 }
 
-#ifdef CONFIG_IEEE80211_WPA
 static int ipw2100_disassociate_bssid(struct ipw2100_priv *priv)
 {
 	struct host_command cmd = {
@@ -4983,34 +4982,6 @@ static int ipw2100_disassociate_bssid(st
 
 	return err;
 }
-#endif
-
-/*
- * Pseudo code for setting up wpa_frame:
- */
-#if 0
-void x(struct ieee80211_assoc_frame *wpa_assoc)
-{
-	struct ipw2100_wpa_assoc_frame frame;
-	frame->fixed_ie_mask = IPW_WPA_CAPABILTIES |
-	    IPW_WPA_LISTENINTERVAL | IPW_WPA_AP_ADDRESS;
-	frame->capab_info = wpa_assoc->capab_info;
-	frame->lisen_interval = wpa_assoc->listent_interval;
-	memcpy(frame->current_ap, wpa_assoc->current_ap, ETH_ALEN);
-
-	/* UNKNOWN -- I'm not postivive about this part; don't have any WPA
-	 * setup here to test it with.
-	 *
-	 * Walk the IEs in the wpa_assoc and figure out the total size of all
-	 * that data.  Stick that into frame->var_ie_len.  Then memcpy() all of
-	 * the IEs from wpa_frame into frame.
-	 */
-	frame->var_ie_len = calculate_ie_len(wpa_assoc);
-	memcpy(frame->var_ie, wpa_assoc->variable, frame->var_ie_len);
-
-	ipw2100_set_wpa_ie(priv, &frame, 0);
-}
-#endif
 
 static int ipw2100_set_wpa_ie(struct ipw2100_priv *,
 			      struct ipw2100_wpa_assoc_frame *, int)
@@ -5750,11 +5721,10 @@ static struct net_device_stats *ipw2100_
 	return &priv->ieee->stats;
 }
 
-/* Support for wpa_supplicant. Will be replaced with WEXT once
- * they get WPA support. */
-#ifdef CONFIG_IEEE80211_WPA
+#if WIRELESS_EXT < 18
+/* Support for wpa_supplicant before WE-18, deprecated. */
 
-/* following definitions must match definitions in driver_ipw2100.c */
+/* following definitions must match definitions in driver_ipw.c */
 
 #define IPW2100_IOCTL_WPA_SUPPLICANT		SIOCIWFIRSTPRIV+30
 
@@ -5792,11 +5762,12 @@ struct ipw2100_param {
 		} wpa_param;
 		struct {
 			u32 len;
-			u8 *data;
+			u8 reserved[32];
+			u8 data[0];
 		} wpa_ie;
 		struct {
-			int command;
-			int reason_code;
+			u32 command;
+			u32 reason_code;
 		} mlme;
 		struct {
 			u8 alg[IPW2100_CRYPT_ALG_NAME_LEN];
@@ -5811,37 +5782,21 @@ struct ipw2100_param {
 	} u;
 };
 
-/* end of driver_ipw2100.c code */
+/* end of driver_ipw.c code */
+#endif				/* WIRELESS_EXT < 18 */
 
 static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value)
 {
-
-	struct ieee80211_device *ieee = priv->ieee;
-	struct ieee80211_security sec = {
-		.flags = SEC_LEVEL | SEC_ENABLED,
-	};
-	int ret = 0;
-
-	ieee->wpa_enabled = value;
-
-	if (value) {
-		sec.level = SEC_LEVEL_3;
-		sec.enabled = 1;
-	} else {
-		sec.level = SEC_LEVEL_0;
-		sec.enabled = 0;
-	}
-
-	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
-	else
-		ret = -EOPNOTSUPP;
-
-	return ret;
+	/* This is called when wpa_supplicant loads and closes the driver
+	 * interface. */
+	priv->ieee->wpa_enabled = value;
+	return 0;
 }
 
-#define AUTH_ALG_OPEN_SYSTEM			0x1
-#define AUTH_ALG_SHARED_KEY			0x2
+#if WIRELESS_EXT < 18
+#define IW_AUTH_ALG_OPEN_SYSTEM			0x1
+#define IW_AUTH_ALG_SHARED_KEY			0x2
+#endif
 
 static int ipw2100_wpa_set_auth_algs(struct ipw2100_priv *priv, int value)
 {
@@ -5852,13 +5807,14 @@ static int ipw2100_wpa_set_auth_algs(str
 	};
 	int ret = 0;
 
-	if (value & AUTH_ALG_SHARED_KEY) {
+	if (value & IW_AUTH_ALG_SHARED_KEY) {
 		sec.auth_mode = WLAN_AUTH_SHARED_KEY;
 		ieee->open_wep = 0;
-	} else {
+	} else if (value & IW_AUTH_ALG_OPEN_SYSTEM) {
 		sec.auth_mode = WLAN_AUTH_OPEN;
 		ieee->open_wep = 1;
-	}
+	} else
+		return -EINVAL;
 
 	if (ieee->set_security)
 		ieee->set_security(ieee->dev, &sec);
@@ -5868,10 +5824,29 @@ static int ipw2100_wpa_set_auth_algs(str
 	return ret;
 }
 
-static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
+void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
+			     char *wpa_ie, int wpa_ie_len)
 {
 
+	struct ipw2100_wpa_assoc_frame frame;
+
+	frame.fixed_ie_mask = 0;
+
+	/* copy WPA IE */
+	memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
+	frame.var_ie_len = wpa_ie_len;
+
+	/* make sure WPA is enabled */
+	ipw2100_wpa_enable(priv, 1);
+	ipw2100_set_wpa_ie(priv, &frame, 0);
+}
+
+#if WIRELESS_EXT < 18
+static int ipw2100_wpa_set_param(struct net_device *dev, u8 name, u32 value)
+{
 	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_crypt_data *crypt;
+	unsigned long flags;
 	int ret = 0;
 
 	switch (name) {
@@ -5880,7 +5855,22 @@ static int ipw2100_wpa_set_param(struct 
 		break;
 
 	case IPW2100_PARAM_TKIP_COUNTERMEASURES:
-		priv->ieee->tkip_countermeasures = value;
+		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
+			IPW_DEBUG_WARNING("Can't set TKIP countermeasures: "
+					  "crypt not set!\n");
+			break;
+		}
+
+		flags = crypt->ops->get_flags(crypt->priv);
+
+		if (value)
+			flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+		else
+			flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+
+		crypt->ops->set_flags(flags, crypt->priv);
+
 		break;
 
 	case IPW2100_PARAM_DROP_UNENCRYPTED:
@@ -5932,23 +5922,6 @@ static int ipw2100_wpa_mlme(struct net_d
 	return ret;
 }
 
-void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv,
-			     char *wpa_ie, int wpa_ie_len)
-{
-
-	struct ipw2100_wpa_assoc_frame frame;
-
-	frame.fixed_ie_mask = 0;
-
-	/* copy WPA IE */
-	memcpy(frame.var_ie, wpa_ie, wpa_ie_len);
-	frame.var_ie_len = wpa_ie_len;
-
-	/* make sure WPA is enabled */
-	ipw2100_wpa_enable(priv, 1);
-	ipw2100_set_wpa_ie(priv, &frame, 0);
-}
-
 static int ipw2100_wpa_set_wpa_ie(struct net_device *dev,
 				  struct ipw2100_param *param, int plen)
 {
@@ -5992,7 +5965,6 @@ static int ipw2100_wpa_set_encryption(st
 				      struct ipw2100_param *param,
 				      int param_len)
 {
-
 	int ret = 0;
 	struct ipw2100_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_device *ieee = priv->ieee;
@@ -6101,8 +6073,8 @@ static int ipw2100_wpa_set_encryption(st
 	if (ops->name != NULL) {
 
 		if (strcmp(ops->name, "WEP") == 0) {
-			memcpy(sec.keys[param->u.crypt.idx], param->u.crypt.key,
-			       param->u.crypt.key_len);
+			memcpy(sec.keys[param->u.crypt.idx],
+			       param->u.crypt.key, param->u.crypt.key_len);
 			sec.key_sizes[param->u.crypt.idx] =
 			    param->u.crypt.key_len;
 			sec.flags |= (1 << param->u.crypt.idx);
@@ -6190,11 +6162,9 @@ static int ipw2100_wpa_supplicant(struct
 	kfree(param);
 	return ret;
 }
-#endif				/* CONFIG_IEEE80211_WPA */
 
 static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
-#ifdef CONFIG_IEEE80211_WPA
 	struct iwreq *wrq = (struct iwreq *)rq;
 	int ret = -1;
 	switch (cmd) {
@@ -6206,10 +6176,9 @@ static int ipw2100_ioctl(struct net_devi
 		return -EOPNOTSUPP;
 	}
 
-#endif				/* CONFIG_IEEE80211_WPA */
-
 	return -EOPNOTSUPP;
 }
+#endif				/* WIRELESS_EXT < 18 */
 
 static void ipw_ethtool_get_drvinfo(struct net_device *dev,
 				    struct ethtool_drvinfo *info)
@@ -6333,10 +6302,15 @@ static struct net_device *ipw2100_alloc_
 	priv->ieee->hard_start_xmit = ipw2100_tx;
 	priv->ieee->set_security = shim__set_security;
 
+	priv->ieee->perfect_rssi = -20;
+	priv->ieee->worst_rssi = -85;
+
 	dev->open = ipw2100_open;
 	dev->stop = ipw2100_close;
 	dev->init = ipw2100_net_init;
+#if WIRELESS_EXT < 18
 	dev->do_ioctl = ipw2100_ioctl;
+#endif
 	dev->get_stats = ipw2100_stats;
 	dev->ethtool_ops = &ipw2100_ethtool_ops;
 	dev->tx_timeout = ipw2100_tx_timeout;
@@ -6362,13 +6336,13 @@ static struct net_device *ipw2100_alloc_
 	/* If power management is turned on, default to AUTO mode */
 	priv->power_mode = IPW_POWER_AUTO;
 
-#ifdef CONFIG_IEEE80211_WPA
+#ifdef CONFIG_IPW2100_MONITOR
+	priv->config |= CFG_CRC_CHECK;
+#endif
 	priv->ieee->wpa_enabled = 0;
-	priv->ieee->tkip_countermeasures = 0;
 	priv->ieee->drop_unencrypted = 0;
 	priv->ieee->privacy_invoked = 0;
 	priv->ieee->ieee802_1x = 1;
-#endif				/* CONFIG_IEEE80211_WPA */
 
 	/* Set module parameters */
 	switch (mode) {
@@ -6429,7 +6403,7 @@ static struct net_device *ipw2100_alloc_
 	INIT_LIST_HEAD(&priv->fw_pend_list);
 	INIT_STAT(&priv->fw_pend_stat);
 
-#ifdef CONFIG_SOFTWARE_SUSPEND2
+#ifdef PF_SYNCTHREAD
 	priv->workqueue = create_workqueue(DRV_NAME, 0);
 #else
 	priv->workqueue = create_workqueue(DRV_NAME);
@@ -6591,7 +6565,6 @@ static int ipw2100_pci_init_one(struct p
 
 	/* perform this after register_netdev so that dev->name is set */
 	sysfs_create_group(&pci_dev->dev.kobj, &ipw2100_attribute_group);
-	netif_carrier_off(dev);
 
 	/* If the RF Kill switch is disabled, go ahead and complete the
 	 * startup sequence */
@@ -6860,10 +6833,6 @@ static int __init ipw2100_init(void)
 	printk(KERN_INFO DRV_NAME ": %s, %s\n", DRV_DESCRIPTION, DRV_VERSION);
 	printk(KERN_INFO DRV_NAME ": %s\n", DRV_COPYRIGHT);
 
-#ifdef CONFIG_IEEE80211_NOWEP
-	IPW_DEBUG_INFO(DRV_NAME ": Compiled with WEP disabled.\n");
-#endif
-
 	ret = pci_module_init(&ipw2100_pci_driver);
 
 #ifdef CONFIG_IPW_DEBUG
@@ -6963,9 +6932,10 @@ static int ipw2100_wx_set_freq(struct ne
 		}
 	}
 
-	if (fwrq->e > 0 || fwrq->m > 1000)
-		return -EOPNOTSUPP;
-	else {			/* Set the channel */
+	if (fwrq->e > 0 || fwrq->m > 1000) {
+		err = -EOPNOTSUPP;
+		goto done;
+	} else {		/* Set the channel */
 		IPW_DEBUG_WX("SET Freq/Channel -> %d \n", fwrq->m);
 		err = ipw2100_set_channel(priv, fwrq->m, 0);
 	}
@@ -7256,7 +7226,7 @@ static int ipw2100_wx_get_wap(struct net
 	 * configured BSSID then return that; otherwise return ANY */
 	if (priv->config & CFG_STATIC_BSSID || priv->status & STATUS_ASSOCIATED) {
 		wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-		memcpy(wrqu->ap_addr.sa_data, &priv->bssid, ETH_ALEN);
+		memcpy(wrqu->ap_addr.sa_data, priv->bssid, ETH_ALEN);
 	} else
 		memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
 
@@ -7711,13 +7681,13 @@ static int ipw2100_wx_get_retry(struct n
 		return -EINVAL;
 
 	if (wrqu->retry.flags & IW_RETRY_MAX) {
-		wrqu->retry.flags = IW_RETRY_LIMIT & IW_RETRY_MAX;
+		wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
 		wrqu->retry.value = priv->long_retry_limit;
 	} else {
 		wrqu->retry.flags =
 		    (priv->short_retry_limit !=
 		     priv->long_retry_limit) ?
-		    IW_RETRY_LIMIT & IW_RETRY_MIN : IW_RETRY_LIMIT;
+		    IW_RETRY_LIMIT | IW_RETRY_MIN : IW_RETRY_LIMIT;
 
 		wrqu->retry.value = priv->short_retry_limit;
 	}
@@ -7847,9 +7817,9 @@ static int ipw2100_wx_get_power(struct n
 
 	struct ipw2100_priv *priv = ieee80211_priv(dev);
 
-	if (!(priv->power_mode & IPW_POWER_ENABLED)) {
+	if (!(priv->power_mode & IPW_POWER_ENABLED))
 		wrqu->power.disabled = 1;
-	} else {
+	else {
 		wrqu->power.disabled = 0;
 		wrqu->power.flags = 0;
 	}
@@ -7859,6 +7829,273 @@ static int ipw2100_wx_get_power(struct n
 	return 0;
 }
 
+#if WIRELESS_EXT > 17
+/*
+ * WE-18 WPA support
+ */
+
+/* SIOCSIWGENIE */
+static int ipw2100_wx_set_genie(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+
+	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee;
+	u8 *buf;
+
+	if (!ieee->wpa_enabled)
+		return -EOPNOTSUPP;
+
+	if (wrqu->data.length > MAX_WPA_IE_LEN ||
+	    (wrqu->data.length && extra == NULL))
+		return -EINVAL;
+
+	if (wrqu->data.length) {
+		buf = kmalloc(wrqu->data.length, GFP_KERNEL);
+		if (buf == NULL)
+			return -ENOMEM;
+
+		memcpy(buf, extra, wrqu->data.length);
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = buf;
+		ieee->wpa_ie_len = wrqu->data.length;
+	} else {
+		kfree(ieee->wpa_ie);
+		ieee->wpa_ie = NULL;
+		ieee->wpa_ie_len = 0;
+	}
+
+	ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
+
+	return 0;
+}
+
+/* SIOCGIWGENIE */
+static int ipw2100_wx_get_genie(struct net_device *dev,
+				struct iw_request_info *info,
+				union iwreq_data *wrqu, char *extra)
+{
+	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee;
+
+	if (ieee->wpa_ie_len == 0 || ieee->wpa_ie == NULL) {
+		wrqu->data.length = 0;
+		return 0;
+	}
+
+	if (wrqu->data.length < ieee->wpa_ie_len)
+		return -E2BIG;
+
+	wrqu->data.length = ieee->wpa_ie_len;
+	memcpy(extra, ieee->wpa_ie, ieee->wpa_ie_len);
+
+	return 0;
+}
+
+/* SIOCSIWAUTH */
+static int ipw2100_wx_set_auth(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee;
+	struct iw_param *param = &wrqu->param;
+	struct ieee80211_crypt_data *crypt;
+	unsigned long flags;
+	int ret = 0;
+
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+	case IW_AUTH_CIPHER_PAIRWISE:
+	case IW_AUTH_CIPHER_GROUP:
+	case IW_AUTH_KEY_MGMT:
+		/*
+		 * ipw2200 does not use these parameters
+		 */
+		break;
+
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
+			IPW_DEBUG_WARNING("Can't set TKIP countermeasures: "
+					  "crypt not set!\n");
+			break;
+		}
+
+		flags = crypt->ops->get_flags(crypt->priv);
+
+		if (param->value)
+			flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+		else
+			flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
+
+		crypt->ops->set_flags(flags, crypt->priv);
+
+		break;
+
+	case IW_AUTH_DROP_UNENCRYPTED:{
+			/* HACK:
+			 *
+			 * wpa_supplicant calls set_wpa_enabled when the driver
+			 * is loaded and unloaded, regardless of if WPA is being
+			 * used.  No other calls are made which can be used to
+			 * determine if encryption will be used or not prior to
+			 * association being expected.  If encryption is not being
+			 * used, drop_unencrypted is set to false, else true -- we
+			 * can use this to determine if the CAP_PRIVACY_ON bit should
+			 * be set.
+			 */
+			struct ieee80211_security sec = {
+				.flags = SEC_ENABLED,
+				.enabled = param->value,
+			};
+			priv->ieee->drop_unencrypted = param->value;
+			/* We only change SEC_LEVEL for open mode. Others
+			 * are set by ipw_wpa_set_encryption.
+			 */
+			if (!param->value) {
+				sec.flags |= SEC_LEVEL;
+				sec.level = SEC_LEVEL_0;
+			} else {
+				sec.flags |= SEC_LEVEL;
+				sec.level = SEC_LEVEL_1;
+			}
+			if (priv->ieee->set_security)
+				priv->ieee->set_security(priv->ieee->dev, &sec);
+			break;
+		}
+
+	case IW_AUTH_80211_AUTH_ALG:
+		ret = ipw2100_wpa_set_auth_algs(priv, param->value);
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		ret = ipw2100_wpa_enable(priv, param->value);
+		break;
+
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		ieee->ieee802_1x = param->value;
+		break;
+
+		//case IW_AUTH_ROAMING_CONTROL:
+	case IW_AUTH_PRIVACY_INVOKED:
+		ieee->privacy_invoked = param->value;
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+	return ret;
+}
+
+/* SIOCGIWAUTH */
+static int ipw2100_wx_get_auth(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct ieee80211_device *ieee = priv->ieee;
+	struct ieee80211_crypt_data *crypt;
+	struct iw_param *param = &wrqu->param;
+	int ret = 0;
+
+	switch (param->flags & IW_AUTH_INDEX) {
+	case IW_AUTH_WPA_VERSION:
+	case IW_AUTH_CIPHER_PAIRWISE:
+	case IW_AUTH_CIPHER_GROUP:
+	case IW_AUTH_KEY_MGMT:
+		/*
+		 * wpa_supplicant will control these internally
+		 */
+		ret = -EOPNOTSUPP;
+		break;
+
+	case IW_AUTH_TKIP_COUNTERMEASURES:
+		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
+		if (!crypt || !crypt->ops->get_flags) {
+			IPW_DEBUG_WARNING("Can't get TKIP countermeasures: "
+					  "crypt not set!\n");
+			break;
+		}
+
+		param->value = (crypt->ops->get_flags(crypt->priv) &
+				IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
+
+		break;
+
+	case IW_AUTH_DROP_UNENCRYPTED:
+		param->value = ieee->drop_unencrypted;
+		break;
+
+	case IW_AUTH_80211_AUTH_ALG:
+		param->value = priv->sec.auth_mode;
+		break;
+
+	case IW_AUTH_WPA_ENABLED:
+		param->value = ieee->wpa_enabled;
+		break;
+
+	case IW_AUTH_RX_UNENCRYPTED_EAPOL:
+		param->value = ieee->ieee802_1x;
+		break;
+
+	case IW_AUTH_ROAMING_CONTROL:
+	case IW_AUTH_PRIVACY_INVOKED:
+		param->value = ieee->privacy_invoked;
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
+/* SIOCSIWENCODEEXT */
+static int ipw2100_wx_set_encodeext(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu, char *extra)
+{
+	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_set_encodeext(priv->ieee, info, wrqu, extra);
+}
+
+/* SIOCGIWENCODEEXT */
+static int ipw2100_wx_get_encodeext(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu, char *extra)
+{
+	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	return ieee80211_wx_get_encodeext(priv->ieee, info, wrqu, extra);
+}
+
+/* SIOCSIWMLME */
+static int ipw2100_wx_set_mlme(struct net_device *dev,
+			       struct iw_request_info *info,
+			       union iwreq_data *wrqu, char *extra)
+{
+	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	struct iw_mlme *mlme = (struct iw_mlme *)extra;
+	u16 reason;
+
+	reason = cpu_to_le16(mlme->reason_code);
+
+	switch (mlme->cmd) {
+	case IW_MLME_DEAUTH:
+		// silently ignore
+		break;
+
+	case IW_MLME_DISASSOC:
+		ipw2100_disassociate_bssid(priv);
+		break;
+
+	default:
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+#endif				/* WIRELESS_EXT > 17 */
+
 /*
  *
  * IWPRIV handlers
@@ -8019,6 +8256,54 @@ static int ipw2100_wx_get_preamble(struc
 	return 0;
 }
 
+#ifdef CONFIG_IPW2100_MONITOR
+static int ipw2100_wx_set_crc_check(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu, char *extra)
+{
+	struct ipw2100_priv *priv = ieee80211_priv(dev);
+	int err, mode = *(int *)extra;
+
+	down(&priv->action_sem);
+	if (!(priv->status & STATUS_INITIALIZED)) {
+		err = -EIO;
+		goto done;
+	}
+
+	if (mode == 1)
+		priv->config |= CFG_CRC_CHECK;
+	else if (mode == 0)
+		priv->config &= ~CFG_CRC_CHECK;
+	else {
+		err = -EINVAL;
+		goto done;
+	}
+	err = 0;
+
+      done:
+	up(&priv->action_sem);
+	return err;
+}
+
+static int ipw2100_wx_get_crc_check(struct net_device *dev,
+				    struct iw_request_info *info,
+				    union iwreq_data *wrqu, char *extra)
+{
+	/*
+	 * This can be called at any time.  No action lock required
+	 */
+
+	struct ipw2100_priv *priv = ieee80211_priv(dev);
+
+	if (priv->config & CFG_CRC_CHECK)
+		snprintf(wrqu->name, IFNAMSIZ, "CRC checked (1)");
+	else
+		snprintf(wrqu->name, IFNAMSIZ, "CRC ignored (0)");
+
+	return 0;
+}
+#endif				/* CONFIG_IPW2100_MONITOR */
+
 static iw_handler ipw2100_wx_handlers[] = {
 	NULL,			/* SIOCSIWCOMMIT */
 	ipw2100_wx_get_name,	/* SIOCGIWNAME */
@@ -8042,7 +8327,11 @@ static iw_handler ipw2100_wx_handlers[] 
 	NULL,			/* SIOCWIWTHRSPY */
 	ipw2100_wx_set_wap,	/* SIOCSIWAP */
 	ipw2100_wx_get_wap,	/* SIOCGIWAP */
+#if WIRELESS_EXT > 17
+	ipw2100_wx_set_mlme,	/* SIOCSIWMLME */
+#else
 	NULL,			/* -- hole -- */
+#endif
 	NULL,			/* SIOCGIWAPLIST -- deprecated */
 	ipw2100_wx_set_scan,	/* SIOCSIWSCAN */
 	ipw2100_wx_get_scan,	/* SIOCGIWSCAN */
@@ -8066,6 +8355,17 @@ static iw_handler ipw2100_wx_handlers[] 
 	ipw2100_wx_get_encode,	/* SIOCGIWENCODE */
 	ipw2100_wx_set_power,	/* SIOCSIWPOWER */
 	ipw2100_wx_get_power,	/* SIOCGIWPOWER */
+#if WIRELESS_EXT > 17
+	NULL,			/* -- hole -- */
+	NULL,			/* -- hole -- */
+	ipw2100_wx_set_genie,	/* SIOCSIWGENIE */
+	ipw2100_wx_get_genie,	/* SIOCGIWGENIE */
+	ipw2100_wx_set_auth,	/* SIOCSIWAUTH */
+	ipw2100_wx_get_auth,	/* SIOCGIWAUTH */
+	ipw2100_wx_set_encodeext,	/* SIOCSIWENCODEEXT */
+	ipw2100_wx_get_encodeext,	/* SIOCGIWENCODEEXT */
+	NULL,			/* SIOCSIWPMKSA */
+#endif
 };
 
 #define IPW2100_PRIV_SET_MONITOR	SIOCIWFIRSTPRIV
@@ -8074,6 +8374,8 @@ static iw_handler ipw2100_wx_handlers[] 
 #define IPW2100_PRIV_GET_POWER		SIOCIWFIRSTPRIV+3
 #define IPW2100_PRIV_SET_LONGPREAMBLE	SIOCIWFIRSTPRIV+4
 #define IPW2100_PRIV_GET_LONGPREAMBLE	SIOCIWFIRSTPRIV+5
+#define IPW2100_PRIV_SET_CRC_CHECK	SIOCIWFIRSTPRIV+6
+#define IPW2100_PRIV_GET_CRC_CHECK	SIOCIWFIRSTPRIV+7
 
 static const struct iw_priv_args ipw2100_private_args[] = {
 
@@ -8099,6 +8401,14 @@ static const struct iw_priv_args ipw2100
 	{
 	 IPW2100_PRIV_GET_LONGPREAMBLE,
 	 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_preamble"},
+#ifdef CONFIG_IPW2100_MONITOR
+	{
+	 IPW2100_PRIV_SET_CRC_CHECK,
+	 IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "set_crc_check"},
+	{
+	 IPW2100_PRIV_GET_CRC_CHECK,
+	 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | IFNAMSIZ, "get_crc_check"},
+#endif				/* CONFIG_IPW2100_MONITOR */
 };
 
 static iw_handler ipw2100_private_handler[] = {
@@ -8113,6 +8423,13 @@ static iw_handler ipw2100_private_handle
 	ipw2100_wx_get_powermode,
 	ipw2100_wx_set_preamble,
 	ipw2100_wx_get_preamble,
+#ifdef CONFIG_IPW2100_MONITOR
+	ipw2100_wx_set_crc_check,
+	ipw2100_wx_get_crc_check,
+#else				/* CONFIG_IPW2100_MONITOR */
+	NULL,
+	NULL,
+#endif				/* CONFIG_IPW2100_MONITOR */
 };
 
 static struct iw_handler_def ipw2100_wx_handler_def = {
@@ -8292,17 +8609,11 @@ static void ipw2100_wx_event_work(struct
 		/* We now have the BSSID, so can finish setting to the full
 		 * associated state */
 		memcpy(wrqu.ap_addr.sa_data, priv->bssid, ETH_ALEN);
-		memcpy(&priv->ieee->bssid, priv->bssid, ETH_ALEN);
+		memcpy(priv->ieee->bssid, priv->bssid, ETH_ALEN);
 		priv->status &= ~STATUS_ASSOCIATING;
 		priv->status |= STATUS_ASSOCIATED;
 		netif_carrier_on(priv->net_dev);
-		if (netif_queue_stopped(priv->net_dev)) {
-			IPW_DEBUG_INFO("Waking net queue.\n");
-			netif_wake_queue(priv->net_dev);
-		} else {
-			IPW_DEBUG_INFO("Starting net queue.\n");
-			netif_start_queue(priv->net_dev);
-		}
+		netif_wake_queue(priv->net_dev);
 	}
 
 	if (!(priv->status & STATUS_ASSOCIATED)) {
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 3eb5c38..99fce99 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
+  Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
 
   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
@@ -475,6 +475,9 @@ enum {
 #define CFG_ADHOC_CREATE        (1<<8)
 #define CFG_C3_DISABLED         (1<<9)
 #define CFG_PASSIVE_SCAN        (1<<10)
+#ifdef CONFIG_IPW2100_MONITOR
+#define CFG_CRC_CHECK           (1<<11)
+#endif
 
 #define CAP_SHARED_KEY          (1<<0)	/* Off = OPEN */
 #define CAP_PRIVACY_ON          (1<<1)	/* Off = No privacy */
@@ -858,9 +861,9 @@ struct ipw2100_rx {
 #define TYPE_ASSOCIATION_REQUEST	0x0013
 #define TYPE_REASSOCIATION_REQUEST	0x0014
 
-#define HW_FEATURE_RFKILL (0x0001)
-#define RF_KILLSWITCH_OFF (1)
-#define RF_KILLSWITCH_ON  (0)
+#define HW_FEATURE_RFKILL 0x0001
+#define RF_KILLSWITCH_OFF 1
+#define RF_KILLSWITCH_ON  0
 
 #define IPW_COMMAND_POOL_SIZE        40
 
---
0.99.8.GIT


--- NEW FILE 2917-Fixed-WEP-on-ipw2100-priv-sec-was-being-used-instead-of.txt ---
Subject: [PATCH] Fixed WEP on ipw2100 (priv->sec was being used instead of
From:  <jketreno at io.(none)>
Date: 1121201130 -0500
priv->ieee->sec)

---

 drivers/net/wireless/ipw2100.c |   97 +++++++++++++++++++++-------------------
 drivers/net/wireless/ipw2100.h |    2 -
 2 files changed, 51 insertions(+), 48 deletions(-)

applies-to: 84ea52f5016b5af30ba029616bfcd3f77e40e2a0
25b645be1e25e16ea7a25678ac195a0e7595c629
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index e7c2221..cf5da20 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -1616,7 +1616,7 @@ static int ipw2100_set_scan_options(stru
 
 	if (!(priv->config & CFG_ASSOCIATE))
 		cmd.host_command_parameters[0] |= IPW_SCAN_NOASSOCIATE;
-	if ((priv->sec.flags & SEC_ENABLED) && priv->sec.enabled)
+	if ((priv->ieee->sec.flags & SEC_ENABLED) && priv->ieee->sec.enabled)
 		cmd.host_command_parameters[0] |= IPW_SCAN_MIXED_CELL;
 	if (priv->config & CFG_PASSIVE_SCAN)
 		cmd.host_command_parameters[0] |= IPW_SCAN_PASSIVE;
@@ -5349,23 +5349,23 @@ static int ipw2100_configure_security(st
 			return err;
 	}
 
-	if (!priv->sec.enabled) {
+	if (!priv->ieee->sec.enabled) {
 		err =
 		    ipw2100_set_security_information(priv, IPW_AUTH_OPEN,
 						     SEC_LEVEL_0, 0, 1);
 	} else {
 		auth_mode = IPW_AUTH_OPEN;
-		if ((priv->sec.flags & SEC_AUTH_MODE) &&
-		    (priv->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
+		if ((priv->ieee->sec.flags & SEC_AUTH_MODE) &&
+		    (priv->ieee->sec.auth_mode == WLAN_AUTH_SHARED_KEY))
 			auth_mode = IPW_AUTH_SHARED;
 
 		sec_level = SEC_LEVEL_0;
-		if (priv->sec.flags & SEC_LEVEL)
-			sec_level = priv->sec.level;
+		if (priv->ieee->sec.flags & SEC_LEVEL)
+			sec_level = priv->ieee->sec.level;
 
 		use_group = 0;
-		if (priv->sec.flags & SEC_UNICAST_GROUP)
-			use_group = priv->sec.unicast_uses_group;
+		if (priv->ieee->sec.flags & SEC_UNICAST_GROUP)
+			use_group = priv->ieee->sec.unicast_uses_group;
 
 		err =
 		    ipw2100_set_security_information(priv, auth_mode, sec_level,
@@ -5375,16 +5375,16 @@ static int ipw2100_configure_security(st
 	if (err)
 		goto exit;
 
-	if (priv->sec.enabled) {
+	if (priv->ieee->sec.enabled) {
 		for (i = 0; i < 4; i++) {
-			if (!(priv->sec.flags & (1 << i))) {
-				memset(priv->sec.keys[i], 0, WEP_KEY_LEN);
-				priv->sec.key_sizes[i] = 0;
+			if (!(priv->ieee->sec.flags & (1 << i))) {
+				memset(priv->ieee->sec.keys[i], 0, WEP_KEY_LEN);
+				priv->ieee->sec.key_sizes[i] = 0;
 			} else {
 				err = ipw2100_set_key(priv, i,
-						      priv->sec.keys[i],
-						      priv->sec.key_sizes[i],
-						      1);
+						      priv->ieee->sec.keys[i],
+						      priv->ieee->sec.
+						      key_sizes[i], 1);
 				if (err)
 					goto exit;
 			}
@@ -5397,8 +5397,8 @@ static int ipw2100_configure_security(st
 	 * encrypted data is sent up */
 	err =
 	    ipw2100_set_wep_flags(priv,
-				  priv->sec.enabled ? IPW_PRIVACY_CAPABLE : 0,
-				  1);
+				  priv->ieee->sec.
+				  enabled ? IPW_PRIVACY_CAPABLE : 0, 1);
 	if (err)
 		goto exit;
 
@@ -5433,58 +5433,61 @@ static void shim__set_security(struct ne
 
 	for (i = 0; i < 4; i++) {
 		if (sec->flags & (1 << i)) {
-			priv->sec.key_sizes[i] = sec->key_sizes[i];
+			priv->ieee->sec.key_sizes[i] = sec->key_sizes[i];
 			if (sec->key_sizes[i] == 0)
-				priv->sec.flags &= ~(1 << i);
+				priv->ieee->sec.flags &= ~(1 << i);
 			else
-				memcpy(priv->sec.keys[i], sec->keys[i],
+				memcpy(priv->ieee->sec.keys[i], sec->keys[i],
 				       sec->key_sizes[i]);
-			priv->sec.flags |= (1 << i);
+			priv->ieee->sec.flags |= (1 << i);
 			priv->status |= STATUS_SECURITY_UPDATED;
 		}
 	}
 
 	if ((sec->flags & SEC_ACTIVE_KEY) &&
-	    priv->sec.active_key != sec->active_key) {
+	    priv->ieee->sec.active_key != sec->active_key) {
 		if (sec->active_key <= 3) {
-			priv->sec.active_key = sec->active_key;
-			priv->sec.flags |= SEC_ACTIVE_KEY;
+			priv->ieee->sec.active_key = sec->active_key;
+			priv->ieee->sec.flags |= SEC_ACTIVE_KEY;
 		} else
-			priv->sec.flags &= ~SEC_ACTIVE_KEY;
+			priv->ieee->sec.flags &= ~SEC_ACTIVE_KEY;
 
 		priv->status |= STATUS_SECURITY_UPDATED;
 	}
 
 	if ((sec->flags & SEC_AUTH_MODE) &&
-	    (priv->sec.auth_mode != sec->auth_mode)) {
-		priv->sec.auth_mode = sec->auth_mode;
-		priv->sec.flags |= SEC_AUTH_MODE;
+	    (priv->ieee->sec.auth_mode != sec->auth_mode)) {
+		priv->ieee->sec.auth_mode = sec->auth_mode;
+		priv->ieee->sec.flags |= SEC_AUTH_MODE;
 		priv->status |= STATUS_SECURITY_UPDATED;
 	}
 
-	if (sec->flags & SEC_ENABLED && priv->sec.enabled != sec->enabled) {
-		priv->sec.flags |= SEC_ENABLED;
-		priv->sec.enabled = sec->enabled;
+	if (sec->flags & SEC_ENABLED && priv->ieee->sec.enabled != sec->enabled) {
+		priv->ieee->sec.flags |= SEC_ENABLED;
+		priv->ieee->sec.enabled = sec->enabled;
 		priv->status |= STATUS_SECURITY_UPDATED;
 		force_update = 1;
 	}
 
-	if (sec->flags & SEC_LEVEL && priv->sec.level != sec->level) {
-		priv->sec.level = sec->level;
-		priv->sec.flags |= SEC_LEVEL;
+	if (sec->flags & SEC_ENCRYPT)
+		priv->ieee->sec.encrypt = sec->encrypt;
+
+	if (sec->flags & SEC_LEVEL && priv->ieee->sec.level != sec->level) {
+		priv->ieee->sec.level = sec->level;
+		priv->ieee->sec.flags |= SEC_LEVEL;
 		priv->status |= STATUS_SECURITY_UPDATED;
 	}
 
 	IPW_DEBUG_WEP("Security flags: %c %c%c%c%c %c%c%c%c\n",
-		      priv->sec.flags & (1 << 8) ? '1' : '0',
-		      priv->sec.flags & (1 << 7) ? '1' : '0',
-		      priv->sec.flags & (1 << 6) ? '1' : '0',
-		      priv->sec.flags & (1 << 5) ? '1' : '0',
-		      priv->sec.flags & (1 << 4) ? '1' : '0',
-		      priv->sec.flags & (1 << 3) ? '1' : '0',
-		      priv->sec.flags & (1 << 2) ? '1' : '0',
-		      priv->sec.flags & (1 << 1) ? '1' : '0',
-		      priv->sec.flags & (1 << 0) ? '1' : '0');
+		      priv->ieee->sec.flags & (1 << 8) ? '1' : '0',
+		      priv->ieee->sec.flags & (1 << 7) ? '1' : '0',
+		      priv->ieee->sec.flags & (1 << 6) ? '1' : '0',
+		      priv->ieee->sec.flags & (1 << 5) ? '1' : '0',
+		      priv->ieee->sec.flags & (1 << 4) ? '1' : '0',
+		      priv->ieee->sec.flags & (1 << 3) ? '1' : '0',
+		      priv->ieee->sec.flags & (1 << 2) ? '1' : '0',
+		      priv->ieee->sec.flags & (1 << 1) ? '1' : '0',
+		      priv->ieee->sec.flags & (1 << 0) ? '1' : '0');
 
 /* As a temporary work around to enable WPA until we figure out why
  * wpa_supplicant toggles the security capability of the driver, which
@@ -5995,17 +5998,19 @@ static int ipw2100_wpa_set_encryption(st
 		return -EINVAL;
 	}
 
+	sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
 	if (strcmp(param->u.crypt.alg, "none") == 0) {
 		if (crypt) {
 			sec.enabled = 0;
+			sec.encrypt = 0;
 			sec.level = SEC_LEVEL_0;
-			sec.flags |= SEC_ENABLED | SEC_LEVEL;
+			sec.flags |= SEC_LEVEL;
 			ieee80211_crypt_delayed_deinit(ieee, crypt);
 		}
 		goto done;
 	}
 	sec.enabled = 1;
-	sec.flags |= SEC_ENABLED;
+	sec.encrypt = 1;
 
 	ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
 	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
@@ -8029,7 +8034,7 @@ static int ipw2100_wx_get_auth(struct ne
 		break;
 
 	case IW_AUTH_80211_AUTH_ALG:
-		param->value = priv->sec.auth_mode;
+		param->value = priv->ieee->sec.auth_mode;
 		break;
 
 	case IW_AUTH_WPA_ENABLED:
diff --git a/drivers/net/wireless/ipw2100.h b/drivers/net/wireless/ipw2100.h
index 99fce99..a1a9cbc 100644
--- a/drivers/net/wireless/ipw2100.h
+++ b/drivers/net/wireless/ipw2100.h
@@ -524,8 +524,6 @@ struct ipw2100_priv {
 
 	int power_mode;
 
-	/* WEP data */
-	struct ieee80211_security sec;
 	int messages_sent;
 
 	int short_retry_limit;
---
0.99.8.GIT


--- NEW FILE 2918-Bug-339-Fix-ipw2100-iwconfig-set-get-txpower.txt ---
Subject: [PATCH] [Bug 339] Fix ipw2100 iwconfig set/get txpower.
From: Liu Hong <hong.liu at intel.com>
Date: 1121275761 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2100.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)

applies-to: 0f4fc7b35be49ce8a9adece8535065f8cc3a1a20
f75459e6f64ca0632f23029e2ca47b424dd33373
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index cf5da20..73287ab 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -5102,6 +5102,10 @@ static int ipw2100_set_tx_power(struct i
 	};
 	int err = 0;
 
+	if (tx_power != IPW_TX_POWER_DEFAULT)
+		tx_power = (tx_power - IPW_TX_POWER_MIN_DBM) * 16 /
+		    (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
+
 	cmd.host_command_parameters[0] = tx_power;
 
 	if (priv->ieee->iw_mode == IW_MODE_ADHOC)
@@ -7523,8 +7527,7 @@ static int ipw2100_wx_set_txpow(struct n
 		    wrqu->txpower.value > IPW_TX_POWER_MAX_DBM)
 			return -EINVAL;
 
-		value = (wrqu->txpower.value - IPW_TX_POWER_MIN_DBM) * 16 /
-		    (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM);
+		value = wrqu->txpower.value;
 	}
 
 	down(&priv->action_sem);
@@ -7564,11 +7567,7 @@ static int ipw2100_wx_get_txpow(struct n
 	} else {
 		wrqu->power.disabled = 0;
 		wrqu->power.fixed = 1;
-		wrqu->power.value =
-		    (priv->tx_power *
-		     (IPW_TX_POWER_MAX_DBM - IPW_TX_POWER_MIN_DBM)) /
-		    (IPW_TX_POWER_MAX - IPW_TX_POWER_MIN) +
-		    IPW_TX_POWER_MIN_DBM;
+		wrqu->power.value = priv->tx_power;
 	}
 
 	wrqu->power.flags = IW_TXPOW_DBM;
---
0.99.8.GIT


--- NEW FILE 2919-Move-code-from-ipw2100_wpa_enable-to-IPW2100_PARAM_DROP_UNENCRYPTED-to.txt ---
Subject: [PATCH] Move code from ipw2100_wpa_enable to IPW2100_PARAM_DROP_UNENCRYPTED to
From: Zhu Yi <yi.zhu at intel.com>
Date: 1121275834 -0500
support wpa_supplicant with open AP. We need this to make driver_ipw
work.

driver_ext has already had the similar code with the WE-18 support
added.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2100.c |   24 +++++++++++++++++++++---
 1 files changed, 21 insertions(+), 3 deletions(-)

applies-to: 4476b0f6df484ed3905de6e12b8802bdfc3c16d4
e4cc28998724661c19cd979a78eaf9a424da52ef
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 73287ab..eaf4707 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -5880,9 +5880,27 @@ static int ipw2100_wpa_set_param(struct 
 
 		break;
 
-	case IPW2100_PARAM_DROP_UNENCRYPTED:
-		priv->ieee->drop_unencrypted = value;
-		break;
+	case IPW2100_PARAM_DROP_UNENCRYPTED:{
+			/* See IW_AUTH_DROP_UNENCRYPTED handling for details */
+			struct ieee80211_security sec = {
+				.flags = SEC_ENABLED,
+				.enabled = value,
+			};
+			priv->ieee->drop_unencrypted = value;
+			/* We only change SEC_LEVEL for open mode. Others
+			 * are set by ipw_wpa_set_encryption.
+			 */
+			if (!value) {
+				sec.flags |= SEC_LEVEL;
+				sec.level = SEC_LEVEL_0;
+			} else {
+				sec.flags |= SEC_LEVEL;
+				sec.level = SEC_LEVEL_1;
+			}
+			if (priv->ieee->set_security)
+				priv->ieee->set_security(priv->ieee->dev, &sec);
+			break;
+		}
 
 	case IPW2100_PARAM_PRIVACY_INVOKED:
 		priv->ieee->privacy_invoked = value;
---
0.99.8.GIT


--- NEW FILE 2920-Catch-ipw2200-up-to-equivelancy-with-v1.0.5.txt ---
Subject: [PATCH] Catch ipw2200 up to equivelancy with v1.0.5
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124946333 -0500

* Fixed #452 problem with setting retry limit (thanks to Hong Liu)
* Fixed #592 race condition during association causing firmware errors
* Fixed #602 problem with building in 64-bit environment
* Fixed #625 problem with SCAN_REQUEST_EXT sometimes failing
* Fixed #645 problem with bit rate not decreasing when moving laptop
  farther from AP
* Fixed #656 problem with 'iwconfig eth1 mode auto' and 'modprobe'
  locking the system
* Fixed #667 problem with "No space for Tx" for hwcrypto=1
* Fixed #685 kernel panic in rmmod caused by led work is still queued
* Fixed #695 problem with network doesn't reassociate after suspend/resume
* Fixed #701 problem with 'iwprvi sw_reset' not resetting the card from
  monitor mode
* Fixed #710 problem with monitor mode being used after a WEP key has
  been configured
* Fixed network->mode vs. priv->ieee->iw_mode checking (thanks to Ben Cahill)
* Fixed "Unknown management packet %d" warning
* Fixed setting channels multiple times in monitor mode causes scan stopped
* Fixed ipw_wx_sw_reset doesn't switch firmware if mode is changed.
* Add duplicate packet checking code (kill ping DUP! and TKIP replay warning)
* Fix hardware encryption (both WEP and AES) doesn't work with fragmentation.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c | 1546 +++++++++++++++++++++++++++++-----------
 drivers/net/wireless/ipw2200.h |   26 +
 2 files changed, 1124 insertions(+), 448 deletions(-)

applies-to: d39518bd2a881f40b649aa5326d08a2679a2567e
afbf30a2b78cac38e6ddae10a73063943b4783ee
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 0a583af..1b6f027 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
 
   802.11 status code portion of this file from ethereal-0.10.6:
     Copyright 2000, Axis Communications AB
@@ -32,7 +32,7 @@
 
 #include "ipw2200.h"
 
-#define IPW2200_VERSION "1.0.4"
+#define IPW2200_VERSION "1.0.5"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2004 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
@@ -273,14 +273,14 @@ static inline u32 __ipw_read32(char *f, 
 
 static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
 #define ipw_read_indirect(a, b, c, d) \
-	IPW_DEBUG_IO("%s %d: read_inddirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
+	IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
 	_ipw_read_indirect(a, b, c, d)
 
 static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
 				int num);
 #define ipw_write_indirect(a, b, c, d) \
 	IPW_DEBUG_IO("%s %d: write_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
-        _ipw_write_indirect(a, b, c, d)
+	_ipw_write_indirect(a, b, c, d)
 
 /* indirect write s */
 static void _ipw_write_reg32(struct ipw_priv *priv, u32 reg, u32 value)
@@ -295,8 +295,6 @@ static void _ipw_write_reg8(struct ipw_p
 	IPW_DEBUG_IO(" reg = 0x%8X : value = 0x%8X\n", reg, value);
 	_ipw_write32(priv, IPW_INDIRECT_ADDR, reg & IPW_INDIRECT_ADDR_MASK);
 	_ipw_write8(priv, IPW_INDIRECT_DATA, value);
-	IPW_DEBUG_IO(" reg = 0x%8lX : value = 0x%8X\n",
-		     (unsigned long)(priv->hw_base + IPW_INDIRECT_DATA), value);
 }
 
 static void _ipw_write_reg16(struct ipw_priv *priv, u32 reg, u16 value)
@@ -1015,12 +1013,12 @@ void ipw_led_init(struct ipw_priv *priv)
 
 void ipw_led_shutdown(struct ipw_priv *priv)
 {
-	cancel_delayed_work(&priv->led_link_on);
-	cancel_delayed_work(&priv->led_link_off);
-	cancel_delayed_work(&priv->led_act_off);
 	ipw_led_activity_off(priv);
 	ipw_led_link_off(priv);
 	ipw_led_band_off(priv);
+	cancel_delayed_work(&priv->led_link_on);
+	cancel_delayed_work(&priv->led_link_off);
+	cancel_delayed_work(&priv->led_act_off);
 }
 
 /*
@@ -1296,6 +1294,7 @@ static ssize_t show_indirect_dword(struc
 {
 	u32 reg = 0;
 	struct ipw_priv *priv = d->driver_data;
+
 	if (priv->status & STATUS_INDIRECT_DWORD)
 		reg = ipw_read_reg32(priv, priv->indirect_dword);
 	else
@@ -1322,6 +1321,7 @@ static ssize_t show_indirect_byte(struct
 {
 	u8 reg = 0;
 	struct ipw_priv *priv = d->driver_data;
+
 	if (priv->status & STATUS_INDIRECT_BYTE)
 		reg = ipw_read_reg8(priv, priv->indirect_byte);
 	else
@@ -1509,8 +1509,8 @@ static ssize_t store_net_stats(struct de
 	return count;
 }
 
-static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO, show_net_stats,
-		   store_net_stats);
+static DEVICE_ATTR(net_stats, S_IWUSR | S_IRUGO,
+		   show_net_stats, store_net_stats);
 
 static void notify_wx_assoc_event(struct ipw_priv *priv)
 {
@@ -1630,6 +1630,11 @@ static void ipw_irq_tasklet(struct ipw_p
 		/* Keep the restart process from trying to send host
 		 * commands by clearing the INIT status bit */
 		priv->status &= ~STATUS_INIT;
+
+		/* Cancel currently queued command. */
+		priv->status &= ~STATUS_HCMD_ACTIVE;
+		wake_up_interruptible(&priv->wait_command_queue);
+
 		queue_work(priv->workqueue, &priv->adapter_restart);
 		handled |= IPW_INTA_BIT_FATAL_ERROR;
 	}
@@ -1796,7 +1801,7 @@ static int ipw_send_system_config(struct
 		return -1;
 	}
 
-	memcpy(&cmd.param, config, sizeof(*config));
+	memcpy(cmd.param, config, sizeof(*config));
 	if (ipw_send_cmd(priv, &cmd)) {
 		IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
 		return -1;
@@ -1817,7 +1822,7 @@ static int ipw_send_ssid(struct ipw_priv
 		return -1;
 	}
 
-	memcpy(&cmd.param, ssid, cmd.len);
+	memcpy(cmd.param, ssid, cmd.len);
 	if (ipw_send_cmd(priv, &cmd)) {
 		IPW_ERROR("failed to send SSID command\n");
 		return -1;
@@ -1841,8 +1846,7 @@ static int ipw_send_adapter_address(stru
 	IPW_DEBUG_INFO("%s: Setting MAC to " MAC_FMT "\n",
 		       priv->net_dev->name, MAC_ARG(mac));
 
-	memcpy(&cmd.param, mac, ETH_ALEN);
-
+	memcpy(cmd.param, mac, ETH_ALEN);
 	if (ipw_send_cmd(priv, &cmd)) {
 		IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
 		return -1;
@@ -1873,11 +1877,6 @@ static void ipw_adapter_restart(void *ad
 		IPW_ERROR("Failed to up device\n");
 		return;
 	}
-
-	if ((priv->capability & CAP_PRIVACY_ON) &&
-	    (priv->ieee->sec.level == SEC_LEVEL_1) &&
-	    !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
-		ipw_set_hwcrypto_keys(priv);
 }
 
 static void ipw_bg_adapter_restart(void *data)
@@ -1917,14 +1916,12 @@ static int ipw_send_scan_request_ext(str
 		.len = sizeof(*request)
 	};
 
-	memcpy(&cmd.param, request, sizeof(*request));
+	memcpy(cmd.param, request, sizeof(*request));
 	if (ipw_send_cmd(priv, &cmd)) {
 		IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
 		return -1;
 	}
 
-	queue_delayed_work(priv->workqueue, &priv->scan_check,
-			   IPW_SCAN_CHECK_WATCHDOG);
 	return 0;
 }
 
@@ -1991,7 +1988,7 @@ static int ipw_send_associate(struct ipw
 		return -1;
 	}
 
-	memcpy(&cmd.param, &tmp_associate, sizeof(*associate));
[...2227 lines suppressed...]
 		memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
 
+		memcpy(priv->country, &priv->eeprom[EEPROM_COUNTRY_CODE], 3);
+		priv->country[3] = '\0';
+		ieee80211_set_geo(priv->ieee, &ipw_geo);
+
 		if (priv->status & STATUS_RF_KILL_SW) {
 			IPW_WARNING("Radio disabled by module parameter.\n");
 			return 0;
@@ -9748,6 +10386,14 @@ static int ipw_up(struct ipw_priv *priv)
 			ipw_led_radio_on(priv);
 			priv->notif_missed_beacons = 0;
 			priv->status |= STATUS_INIT;
+
+			/* Set hardware WEP key if it is configured. */
+			if ((priv->capability & CAP_PRIVACY_ON) &&
+			    (priv->ieee->sec.level == SEC_LEVEL_1) &&
+			    !(priv->ieee->host_encrypt ||
+			      priv->ieee->host_decrypt))
+				ipw_set_hwcrypto_keys(priv);
+
 			return 0;
 		}
 
@@ -9846,6 +10492,7 @@ static void ipw_bg_down(void *data)
 	up(&priv->sem);
 }
 
+#if WIRELESS_EXT < 18
 static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	struct iwreq *wrq = (struct iwreq *)rq;
@@ -9861,6 +10508,7 @@ static int ipw_ioctl(struct net_device *
 
 	return -EOPNOTSUPP;
 }
+#endif
 
 /* Called by register_netdev() */
 static int ipw_net_init(struct net_device *dev)
@@ -9942,6 +10590,7 @@ static int ipw_pci_probe(struct pci_dev 
 	void __iomem *base;
 	u32 length, val;
 	struct ipw_priv *priv;
+	int i;
 
 	net_dev = alloc_ieee80211(sizeof(struct ipw_priv));
 	if (net_dev == NULL) {
@@ -9958,6 +10607,8 @@ static int ipw_pci_probe(struct pci_dev 
 	ipw_debug_level = debug;
 #endif
 	spin_lock_init(&priv->lock);
+	for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++)
+		INIT_LIST_HEAD(&priv->ibss_mac_hash[i]);
 
 	init_MUTEX(&priv->sem);
 	if (pci_enable_device(pdev)) {
@@ -10035,7 +10686,9 @@ static int ipw_pci_probe(struct pci_dev 
 	net_dev->open = ipw_net_open;
 	net_dev->stop = ipw_net_stop;
 	net_dev->init = ipw_net_init;
+#if WIRELESS_EXT < 18
 	net_dev->do_ioctl = ipw_ioctl;
+#endif
 	net_dev->get_stats = ipw_net_get_stats;
 	net_dev->set_multicast_list = ipw_net_set_multicast_list;
 	net_dev->set_mac_address = ipw_net_set_mac_address;
@@ -10086,13 +10739,18 @@ static int ipw_pci_probe(struct pci_dev 
 static void ipw_pci_remove(struct pci_dev *pdev)
 {
 	struct ipw_priv *priv = pci_get_drvdata(pdev);
+	struct list_head *p, *q;
+	int i;
 
 	if (!priv)
 		return;
 
 	down(&priv->sem);
+
+	priv->status |= STATUS_EXIT_PENDING;
 	ipw_down(priv);
 	sysfs_remove_group(&pdev->dev.kobj, &ipw_attribute_group);
+
 	up(&priv->sem);
 
 	unregister_netdev(priv->net_dev);
@@ -10113,21 +10771,21 @@ static void ipw_pci_remove(struct pci_de
 	destroy_workqueue(priv->workqueue);
 	priv->workqueue = NULL;
 
+	/* Free MAC hash list for ADHOC */
+	for (i = 0; i < IPW_IBSS_MAC_HASH_SIZE; i++) {
+		list_for_each_safe(p, q, &priv->ibss_mac_hash[i]) {
+			kfree(list_entry(p, struct ipw_ibss_seq, list));
+			list_del(p);
+		}
+	}
+
 	free_irq(pdev->irq, priv);
 	iounmap(priv->hw_base);
 	pci_release_regions(pdev);
 	pci_disable_device(pdev);
 	pci_set_drvdata(pdev, NULL);
 	free_ieee80211(priv->net_dev);
-
-#ifdef CONFIG_PM
-	if (fw_loaded) {
-		release_firmware(bootfw);
-		release_firmware(ucode);
-		release_firmware(firmware);
-		fw_loaded = 0;
-	}
-#endif
+	free_firmware();
 }
 
 #ifdef CONFIG_PM
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 9dbd73a..915f469 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -244,7 +244,7 @@ enum connection_manager_assoc_states {
 #define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED       31
 
 #define HOST_NOTIFICATION_STATUS_BEACON_MISSING         1
-#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT           24
+#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT           9
 #define IPW_MB_ROAMING_THRESHOLD_DEFAULT                8
 #define IPW_REAL_RATE_RX_PACKET_THRESHOLD               300
 
@@ -699,8 +699,8 @@ struct ipw_rx_packet {
 } __attribute__ ((packed));
 
 #define IPW_RX_NOTIFICATION_SIZE sizeof(struct ipw_rx_header) + 12
-#define IPW_RX_FRAME_SIZE        sizeof(struct ipw_rx_header) + \
-                                 sizeof(struct ipw_rx_frame)
+#define IPW_RX_FRAME_SIZE        (unsigned int)(sizeof(struct ipw_rx_header) + \
+                                 sizeof(struct ipw_rx_frame))
 
 struct ipw_rx_mem_buffer {
 	dma_addr_t dma_addr;
@@ -1029,6 +1029,7 @@ struct ipw_cmd {
 #define STATUS_SCAN_PENDING     (1<<20)
 #define STATUS_SCANNING         (1<<21)
 #define STATUS_SCAN_ABORTING    (1<<22)
+#define STATUS_SCAN_FORCED      (1<<23)
 
 #define STATUS_LED_LINK_ON      (1<<24)
 #define STATUS_LED_ACT_ON       (1<<25)
@@ -1074,6 +1075,15 @@ struct average {
 };
 
 #define MAX_SPEED_SCAN 100
+#define IPW_IBSS_MAC_HASH_SIZE 31
+
+struct ipw_ibss_seq {
+	u8 mac[ETH_ALEN];
+	u16 seq_num;
+	u16 frag_num;
+	unsigned long packet_time;
+	struct list_head list;
+};
 
 struct ipw_priv {
 	/* ieee device used by generic ieee processing code */
@@ -1115,7 +1125,7 @@ struct ipw_priv {
 	int rx_bufs_min;	  /**< minimum number of bufs in Rx queue */
 	int rx_pend_max;	  /**< maximum pending buffers for one IRQ */
 	u32 hcmd_seq;		  /**< sequence number for hcmd */
-	u32 missed_beacon_threshold;
+	u32 disassociate_threshold;
 	u32 roaming_threshold;
 
 	struct ipw_associate assoc_request;
@@ -1156,6 +1166,8 @@ struct ipw_priv {
 	u8 mac_addr[ETH_ALEN];
 	u8 num_stations;
 	u8 stations[MAX_STATIONS][ETH_ALEN];
+	u8 short_retry_limit;
+	u8 long_retry_limit;
 
 	u32 notif_missed_beacons;
 
@@ -1176,8 +1188,14 @@ struct ipw_priv {
 	u8 speed_scan[MAX_SPEED_SCAN];
 	u8 speed_scan_pos;
 
+	u16 last_seq_num;
+	u16 last_frag_num;
+	unsigned long last_packet_time;
+	struct list_head ibss_mac_hash[IPW_IBSS_MAC_HASH_SIZE];
+
 	/* eeprom */
 	u8 eeprom[0x100];	/* 256 bytes of eeprom */
+	u8 country[4];
 	int eeprom_delay;
 
 	struct iw_statistics wstats;
---
0.99.8.GIT


--- NEW FILE 2921-Fix-hardware-encryption-both-WEP-and-AES-doesn-t-work-with-fragmentation.txt ---
Subject: [PATCH] Fix hardware encryption (both WEP and AES) doesn't work with fragmentation.
From: Zhu Yi <yi.zhu at intel.com>
Date: 1121275491 -0500
Firmware sends received packets with double sized ICV/MIC.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   10 ++++++++--
 1 files changed, 8 insertions(+), 2 deletions(-)

applies-to: 24c583520cdb77e22631741358831e10c865bde0
a2d73e60bb018da74ba508943c79c83659f3a883
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 1b6f027..8f7e9ac 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -7587,7 +7587,10 @@ static void ipw_rebuild_decrypted_skb(st
 		memmove(skb->data + IEEE80211_3ADDR_LEN,
 			skb->data + IEEE80211_3ADDR_LEN + 8,
 			skb->len - IEEE80211_3ADDR_LEN - 8);
-		skb_trim(skb, skb->len - 8);	/* MIC */
+		if (fc & IEEE80211_FCTL_MOREFRAGS)
+			skb_trim(skb, skb->len - 16);	/* 2*MIC */
+		else
+			skb_trim(skb, skb->len - 8);	/* MIC */
 		break;
 	case SEC_LEVEL_2:
 		break;
@@ -7596,7 +7599,10 @@ static void ipw_rebuild_decrypted_skb(st
 		memmove(skb->data + IEEE80211_3ADDR_LEN,
 			skb->data + IEEE80211_3ADDR_LEN + 4,
 			skb->len - IEEE80211_3ADDR_LEN - 4);
-		skb_trim(skb, skb->len - 4);	/* ICV */
+		if (fc & IEEE80211_FCTL_MOREFRAGS)
+			skb_trim(skb, skb->len - 8);	/* 2*ICV */
+		else
+			skb_trim(skb, skb->len - 4);	/* ICV */
 		break;
 	case SEC_LEVEL_0:
 		break;
---
0.99.8.GIT


--- NEW FILE 2922-Fix-is_duplicate_packet-bug-for-fragmentation-number-setting.txt ---
Subject: [PATCH] Fix is_duplicate_packet() bug for fragmentation number setting.
From: Zhu Yi <yi.zhu at intel.com>
Date: 1121275335 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: f657e3b54634c5b05f100ed8df7f47a8f3b2ff39
f57ce7ce9c7498fe9c4090aaf389c89f3bd70f7e
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 8f7e9ac..93ed871 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -7754,10 +7754,10 @@ static inline int is_duplicate_packet(st
 		if (*last_frag + 1 != frag)
 			/* out-of-order fragment */
 			goto drop;
-		*last_frag = frag;
 	} else
 		*last_seq = seq;
 
+	*last_frag = frag;
 	*last_time = jiffies;
 	return 0;
 
---
0.99.8.GIT


--- NEW FILE 2923-bug-667-Fix-the-notorious-No-space-for-Tx-bug.txt ---
Subject: [PATCH] [bug 667] Fix the notorious "No space for Tx" bug.
From: Zhu Yi <yi.zhu at intel.com>
Date: 1121275538 -0500

We send SYSTEM_CONFIG command after the TGI_KEY command if hardware
encryption is enabled. It sometimes causes a firmware stall (firmware
doesn't respond to any request) and finally bungs up the Tx send queue.
The solution is to send SYSTEM_CONFIG command in the post association
stage from a workqueue.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   46 ++++++++++++++++++++--------------------
 drivers/net/wireless/ipw2200.h |    1 +
 2 files changed, 24 insertions(+), 23 deletions(-)

applies-to: 32abe5aa737774ee376a52cc47b31a7162a02f69
d8bad6df045249cd1cff6a0d167c8f1b9caade7e
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 93ed871..f3048f8 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -3589,6 +3589,12 @@ static void ipw_bg_disassociate(void *da
 	up(&priv->sem);
 }
 
+static void ipw_system_config(void *data)
+{
+	struct ipw_priv *priv = data;
+	ipw_send_system_config(priv, &priv->sys_config);
+}
+
 struct ipw_status_code {
 	u16 status;
 	const char *reason;
@@ -4060,6 +4066,8 @@ static inline void ipw_rx_notification(s
 
 					priv->status &= ~STATUS_ASSOCIATING;
 					priv->status |= STATUS_ASSOCIATED;
+					queue_work(priv->workqueue,
+						   &priv->system_config);
 
 #ifdef CONFIG_IPW_QOS
 #define IPW_GET_PACKET_STYPE(x) WLAN_FC_GET_STYPE( \
@@ -5553,45 +5561,36 @@ static void ipw_set_hwcrypto_keys(struct
 {
 	switch (priv->ieee->sec.level) {
 	case SEC_LEVEL_3:
-		if (!(priv->ieee->sec.flags & SEC_ACTIVE_KEY))
-			break;
+		if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
+			ipw_send_tgi_tx_key(priv,
+					    DCT_FLAG_EXT_SECURITY_CCM,
+					    priv->ieee->sec.active_key);
 
-		ipw_send_tgi_tx_key(priv, DCT_FLAG_EXT_SECURITY_CCM,
-				    priv->ieee->sec.active_key);
 		ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
-
 		priv->sys_config.disable_unicast_decryption = 0;
 		priv->sys_config.disable_multicast_decryption = 0;
 		priv->ieee->host_decrypt = 0;
-		if (ipw_send_system_config(priv, &priv->sys_config))
-			IPW_ERROR("ipw_send_system_config failed\n");
-
 		break;
 	case SEC_LEVEL_2:
-		if (!(priv->ieee->sec.flags & SEC_ACTIVE_KEY))
-			break;
-
-		ipw_send_tgi_tx_key(priv, DCT_FLAG_EXT_SECURITY_TKIP,
-				    priv->ieee->sec.active_key);
+		if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
+			ipw_send_tgi_tx_key(priv,
+					    DCT_FLAG_EXT_SECURITY_TKIP,
+					    priv->ieee->sec.active_key);
 
 		priv->sys_config.disable_unicast_decryption = 1;
 		priv->sys_config.disable_multicast_decryption = 1;
 		priv->ieee->host_decrypt = 1;
-		if (ipw_send_system_config(priv, &priv->sys_config))
-			IPW_ERROR("ipw_send_system_config failed\n");
-
 		break;
 	case SEC_LEVEL_1:
 		ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
-
 		priv->sys_config.disable_unicast_decryption = 0;
 		priv->sys_config.disable_multicast_decryption = 0;
 		priv->ieee->host_decrypt = 0;
-		if (ipw_send_system_config(priv, &priv->sys_config))
-			IPW_ERROR("ipw_send_system_config failed\n");
-
 		break;
 	case SEC_LEVEL_0:
+		priv->sys_config.disable_unicast_decryption = 1;
+		priv->sys_config.disable_multicast_decryption = 1;
+		break;
 	default:
 		break;
 	}
@@ -10113,6 +10112,7 @@ static int ipw_setup_deferred_work(struc
 	INIT_WORK(&priv->adhoc_check, ipw_bg_adhoc_check, priv);
 	INIT_WORK(&priv->associate, ipw_bg_associate, priv);
 	INIT_WORK(&priv->disassociate, ipw_bg_disassociate, priv);
+	INIT_WORK(&priv->system_config, ipw_system_config, priv);
 	INIT_WORK(&priv->rx_replenish, ipw_bg_rx_queue_replenish, priv);
 	INIT_WORK(&priv->adapter_restart, ipw_bg_adapter_restart, priv);
 	INIT_WORK(&priv->rf_kill, ipw_bg_rf_kill, priv);
@@ -10206,10 +10206,10 @@ static void shim__set_security(struct ne
 		priv->ieee->sec.level = sec->level;
 		priv->ieee->sec.flags |= SEC_LEVEL;
 		priv->status |= STATUS_SECURITY_UPDATED;
-	}
 
-	if (!priv->ieee->host_encrypt)
-		ipw_set_hwcrypto_keys(priv);
+		if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
+			ipw_set_hwcrypto_keys(priv);
+	}
 
 	/* To match current functionality of ipw2100 (which works well w/
 	 * various supplicants, we don't force a disassociate if the
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 915f469..28667d3 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1205,6 +1205,7 @@ struct ipw_priv {
 	struct work_struct adhoc_check;
 	struct work_struct associate;
 	struct work_struct disassociate;
+	struct work_struct system_config;
 	struct work_struct rx_replenish;
 	struct work_struct request_scan;
 	struct work_struct adapter_restart;
---
0.99.8.GIT


--- NEW FILE 2924-Bug-637-Set-tx-power-for-A-band.txt ---
Subject: [PATCH] [Bug 637] Set tx power for A band.
From: Liu Hong <hong.liu at intel.com>
Date: 1121275637 -0500

It uses the ieee80211-geo info to set the tx power of the a/b/g band.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   31 ++++++++++++++++++++++++++++---
 1 files changed, 28 insertions(+), 3 deletions(-)

applies-to: 356a0688be3efd57fa0d7182f30bba6887986750
8400a1ceb445f2ace4b8d3c35c181b2b416a81ce
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index f3048f8..0923038 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8756,6 +8756,7 @@ static int ipw_wx_set_txpow(struct net_d
 			    union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
+	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
 	struct ipw_tx_power tx_power;
 	int i;
 
@@ -8785,10 +8786,15 @@ static int ipw_wx_set_txpow(struct net_d
 
 	/* configure device for 'G' band */
 	tx_power.ieee_mode = IPW_G_MODE;
-	tx_power.num_channels = 11;
-	for (i = 0; i < 11; i++) {
+	tx_power.num_channels = geo->bg_channels;
+	for (i = 0; i < geo->bg_channels; i++) {
+		int max_power = geo->bg[i].max_power;
+
 		tx_power.channels_tx_power[i].channel_number = i + 1;
-		tx_power.channels_tx_power[i].tx_power = priv->tx_power;
+		if (max_power != 0 && priv->tx_power > max_power)
+			tx_power.channels_tx_power[i].tx_power = max_power;
+		else
+			tx_power.channels_tx_power[i].tx_power = priv->tx_power;
 	}
 	if (ipw_send_tx_power(priv, &tx_power))
 		goto error;
@@ -8798,6 +8804,25 @@ static int ipw_wx_set_txpow(struct net_d
 	if (ipw_send_tx_power(priv, &tx_power))
 		goto error;
 
+	/* configure device to also handle 'A' band */
+	if (priv->ieee->abg_true) {
+		tx_power.ieee_mode = IPW_A_MODE;
+		tx_power.num_channels = geo->a_channels;
+		for (i = 0; i < geo->a_channels; i++) {
+			int max_power = geo->a[i].max_power;
+
+			tx_power.channels_tx_power[i].channel_number = i + 1;
+			if (max_power != 0 && priv->tx_power > max_power)
+				tx_power.channels_tx_power[i].tx_power =
+				    max_power;
+			else
+				tx_power.channels_tx_power[i].tx_power =
+				    priv->tx_power;
+		}
+		if (ipw_send_tx_power(priv, &tx_power))
+			goto error;
+	}
+
 	up(&priv->sem);
 	return 0;
 
---
0.99.8.GIT


--- NEW FILE 2925-Changed-default-of-missed-beacons-to-miss-before-disassociation-to-24.txt ---
Subject: [PATCH] Changed default # of missed beacons to miss before disassociation to 24
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1121355305 -0500
(vs. 9 which is too low in most environments)

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.h |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 9ee014ce0dfbbf4b66ff39d2788b6352cadcfd3e
d2021cb4e28c512c395a439d65556c260b94e47e
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 28667d3..9bf8aa4 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -244,7 +244,7 @@ enum connection_manager_assoc_states {
 #define HOST_NOTIFICATION_S36_MEASUREMENT_REFUSED       31
 
 #define HOST_NOTIFICATION_STATUS_BEACON_MISSING         1
-#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT           9
+#define IPW_MB_DISASSOCIATE_THRESHOLD_DEFAULT           24
 #define IPW_MB_ROAMING_THRESHOLD_DEFAULT                8
 #define IPW_REAL_RATE_RX_PACKET_THRESHOLD               300
 
---
0.99.8.GIT


--- NEW FILE 2926-Updated-to-support-ieee80211-callback-to-is_queue_full-for-802.11e.txt ---
Subject: [PATCH] Updated to support ieee80211 callback to is_queue_full for 802.11e
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1122585955 -0500
support.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   40 +++++++++++++++++++++++++++++++---------
 1 files changed, 31 insertions(+), 9 deletions(-)

applies-to: 63638ef78628bb907044f7fce29423fc0a334e49
227d2dc1f109e3348564320cf42fc56770428ed3
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 0923038..3b3a4a0 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -9654,8 +9654,8 @@ modify to send one tfd per fragment inst
 we need to heavily modify the ieee80211_skb_to_txb.
 */
 
-static inline void ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
-			      int pri)
+static inline int ipw_tx_skb(struct ipw_priv *priv, struct ieee80211_txb *txb,
+			     int pri)
 {
 	struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)
 	    txb->fragments[0]->data;
@@ -9672,6 +9672,11 @@ static inline void ipw_tx_skb(struct ipw
 	u16 remaining_bytes;
 	int fc;
 
+	/* If there isn't room in the queue, we return busy and let the
+	 * network stack requeue the packet for us */
+	if (ipw_queue_space(q) < q->high_mark)
+		return NETDEV_TX_BUSY;
+
 	switch (priv->ieee->iw_mode) {
 	case IW_MODE_ADHOC:
 		hdr_len = IEEE80211_3ADDR_LEN;
@@ -9837,14 +9842,28 @@ static inline void ipw_tx_skb(struct ipw
 	q->first_empty = ipw_queue_inc_wrap(q->first_empty, q->n_bd);
 	ipw_write32(priv, q->reg_w, q->first_empty);
 
-	if (ipw_queue_space(q) < q->high_mark)
-		netif_stop_queue(priv->net_dev);
-
-	return;
+	return NETDEV_TX_OK;
 
       drop:
 	IPW_DEBUG_DROP("Silently dropping Tx packet.\n");
 	ieee80211_txb_free(txb);
+	return NETDEV_TX_OK;
+}
+
+static int ipw_net_is_queue_full(struct net_device *dev, int pri)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+#ifdef CONFIG_IPW_QOS
+	int tx_id = ipw_get_tx_queue_number(priv, pri);
+	struct clx2_tx_queue *txq = &priv->txq[tx_id];
+#else
+	struct clx2_tx_queue *txq = &priv->txq[0];
+#endif				/* CONFIG_IPW_QOS */
+
+	if (ipw_queue_space(&txq->q) < txq->q.high_mark)
+		return 1;
+
+	return 0;
 }
 
 static int ipw_net_hard_start_xmit(struct ieee80211_txb *txb,
@@ -9852,6 +9871,7 @@ static int ipw_net_hard_start_xmit(struc
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	unsigned long flags;
+	int ret;
 
 	IPW_DEBUG_TX("dev->xmit(%d bytes)\n", txb->payload_size);
 	spin_lock_irqsave(&priv->lock, flags);
@@ -9863,11 +9883,12 @@ static int ipw_net_hard_start_xmit(struc
 		goto fail_unlock;
 	}
 
-	ipw_tx_skb(priv, txb, pri);
-	__ipw_led_activity_on(priv);
+	ret = ipw_tx_skb(priv, txb, pri);
+	if (ret == NETDEV_TX_OK)
+		__ipw_led_activity_on(priv);
 	spin_unlock_irqrestore(&priv->lock, flags);
 
-	return 0;
+	return ret;
 
       fail_unlock:
 	spin_unlock_irqrestore(&priv->lock, flags);
@@ -10706,6 +10727,7 @@ static int ipw_pci_probe(struct pci_dev 
 
 	priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
 	priv->ieee->set_security = shim__set_security;
+	priv->ieee->is_queue_full = ipw_net_is_queue_full;
 
 #ifdef CONFIG_IPW_QOS
 	priv->ieee->handle_management_frame = ipw_handle_management_frame;
---
0.99.8.GIT


--- NEW FILE 2927-Fixed-some-compiler-issues-if-CONFIG_IPW2200_QOS-is-enabled.txt ---
Subject: [PATCH] Fixed some compiler issues if CONFIG_IPW2200_QOS is enabled.
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1123119194 -0500
Updated a copyright date.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   13 ++++++-------
 1 files changed, 6 insertions(+), 7 deletions(-)

applies-to: 0f3b2c85592e8ea4cdd998e10e9308d69b2d954d
2b184d5b5401bf87036cd0c2a0242fa5320129d7
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 3b3a4a0..073721f 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -34,7 +34,7 @@
 
 #define IPW2200_VERSION "1.0.5"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
-#define DRV_COPYRIGHT	"Copyright(c) 2003-2004 Intel Corporation"
+#define DRV_COPYRIGHT	"Copyright(c) 2003-2005 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
 
 #define ETH_P_80211_STATS (ETH_P_80211_RAW + 1)
@@ -4077,7 +4077,7 @@ static inline void ipw_rx_notification(s
 					     == IEEE80211_STYPE_ASSOC_RESP)) {
 						if ((sizeof
 						     (struct
-						      ieee80211_assoc_response_frame)
+						      ieee80211_assoc_response)
 						     <= notif->size)
 						    && (notif->size <= 2314)) {
 							struct
@@ -4095,7 +4095,7 @@ static inline void ipw_rx_notification(s
 							ieee80211_rx_mgt(priv->
 									 ieee,
 									 (struct
-									  ieee80211_hdr
+									  ieee80211_hdr_4addr
 									  *)
 									 &notif->u.raw, &stats);
 						}
@@ -7154,9 +7154,8 @@ static void ipw_bg_qos_activate(void *da
 /*
 * Handler for probe responce and beacon frame
 */
-static int ipw_handle_management_frame(struct net_device *dev,
-				       struct ieee80211_network *network,
-				       u16 type)
+static int ipw_handle_management(struct net_device *dev,
+				 struct ieee80211_network *network, u16 type)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int active_network;
@@ -10730,7 +10729,7 @@ static int ipw_pci_probe(struct pci_dev 
 	priv->ieee->is_queue_full = ipw_net_is_queue_full;
 
 #ifdef CONFIG_IPW_QOS
-	priv->ieee->handle_management_frame = ipw_handle_management_frame;
+	priv->ieee->handle_management = ipw_handle_management;
 #endif				/* CONFIG_IPW_QOS */
 
 	priv->ieee->perfect_rssi = -20;
---
0.99.8.GIT


--- NEW FILE 2928-Added-more-useful-geography-encoding-so-people-s-experience-with.txt ---
Subject: [PATCH] Added more useful geography encoding so people's experience with
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1123119416 -0500
iwconfig matches what their hardware can actually do in regard to
supported channel maps, etc.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |  279 +++++++++++++++++++++++++++++++++++++---
 1 files changed, 259 insertions(+), 20 deletions(-)

applies-to: 2075dcadc11cf2cdf63b03492197c55d8225fe84
4f36f8088ada6c63719a970616078887f82e226c
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 073721f..6e79ae2 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -10374,28 +10374,256 @@ static int ipw_config(struct ipw_priv *p
 	return -EIO;
 }
 
-static const struct ieee80211_geo ipw_geo = {
-	"---",
-	.bg_channels = 11,
-	.bg = {{2412, 1}, {2417, 2}, {2422, 3},
-	       {2427, 4}, {2432, 5}, {2437, 6},
-	       {2442, 7}, {2447, 8}, {2452, 9},
-	       {2457, 10}, {2462, 11}},
-	.a_channels = 8,
-	.a = {{5180, 36},
-	      {5200, 40},
-	      {5220, 44},
-	      {5240, 48},
-	      {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
-	      {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
-	      {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
-	      {5320, 64, IEEE80211_CH_PASSIVE_ONLY}},
+/*
+ * NOTE:
+ *
+ * These tables have been tested in conjunction with the
+ * Intel PRO/Wireless 2200BG and 2915ABG Network Connection Adapters.
+ *
+ * Altering this values, using it on other hardware, or in geographies
+ * not intended for resale of the above mentioned Intel adapters has
+ * not been tested.
+ *
+ */
+static const struct ieee80211_geo ipw_geos[] = {
+	{			/* Restricted */
+	 "---",
+	 .bg_channels = 11,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}},
+	 },
+
+	{			/* Custom US/Canada */
+	 "ZZF",
+	 .bg_channels = 11,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}},
+	 .a_channels = 8,
+	 .a = {{5180, 36},
+	       {5200, 40},
+	       {5220, 44},
+	       {5240, 48},
+	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY}},
+	 },
+
+	{			/* Rest of World */
+	 "ZZD",
+	 .bg_channels = 13,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}, {2467, 12},
+		{2472, 13}},
+	 },
+
+	{			/* Custom USA & Europe & High */
+	 "ZZA",
+	 .bg_channels = 11,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}},
+	 .a_channels = 13,
+	 .a = {{5180, 36},
+	       {5200, 40},
+	       {5220, 44},
+	       {5240, 48},
+	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+	       {5745, 149},
+	       {5765, 153},
+	       {5785, 157},
+	       {5805, 161},
+	       {5825, 165}},
+	 },
+
+	{			/* Custom NA & Europe */
+	 "ZZB",
+	 .bg_channels = 11,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}},
+	 .a_channels = 13,
+	 .a = {{5180, 36},
+	       {5200, 40},
+	       {5220, 44},
+	       {5240, 48},
+	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+	       {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
+	       {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
+	       {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
+	       {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
+	       {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
+	 },
+
+	{			/* Custom Japan */
+	 "ZZC",
+	 .bg_channels = 11,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}},
+	 .a_channels = 4,
+	 .a = {{5170, 34}, {5190, 38},
+	       {5210, 42}, {5230, 46}},
+	 },
+
+	{			/* Custom */
+	 "ZZM",
+	 .bg_channels = 11,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}},
+	 },
+
+	{			/* Europe */
+	 "ZZE",
+	 .bg_channels = 13,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}, {2467, 12},
+		{2472, 13}},
+	 .a_channels = 19,
+	 .a = {{5180, 36},
+	       {5200, 40},
+	       {5220, 44},
+	       {5240, 48},
+	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+	       {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
+	       {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
+	       {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
+	       {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
+	       {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
+	       {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
+	       {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
+	       {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
+	       {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
+	       {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
+	       {5700, 140, IEEE80211_CH_PASSIVE_ONLY}},
+	 },
+
+	{			/* Custom Japan */
+	 "ZZJ",
+	 .bg_channels = 14,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}, {2467, 12},
+		{2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY}},
+	 .a_channels = 4,
+	 .a = {{5170, 34}, {5190, 38},
+	       {5210, 42}, {5230, 46}},
+	 },
+
+	{			/* High Band */
+	 "ZZH",
+	 .bg_channels = 13,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11},
+		{2467, 12, IEEE80211_CH_PASSIVE_ONLY},
+		{2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
+	 .a_channels = 4,
+	 .a = {{5745, 149}, {5765, 153},
+	       {5785, 157}, {5805, 161}},
+	 },
+
+	{			/* Custom Europe */
+	 "ZZG",
+	 .bg_channels = 13,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11},
+		{2467, 12}, {2472, 13}},
+	 .a_channels = 4,
+	 .a = {{5180, 36}, {5200, 40},
+	       {5220, 44}, {5240, 48}},
+	 },
+
+	{			/* Europe */
+	 "ZZK",
+	 .bg_channels = 13,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11},
+		{2467, 12, IEEE80211_CH_PASSIVE_ONLY},
+		{2472, 13, IEEE80211_CH_PASSIVE_ONLY}},
+	 .a_channels = 24,
+	 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
+	       {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
+	       {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
+	       {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
+	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+	       {5500, 100, IEEE80211_CH_PASSIVE_ONLY},
+	       {5520, 104, IEEE80211_CH_PASSIVE_ONLY},
+	       {5540, 108, IEEE80211_CH_PASSIVE_ONLY},
+	       {5560, 112, IEEE80211_CH_PASSIVE_ONLY},
+	       {5580, 116, IEEE80211_CH_PASSIVE_ONLY},
+	       {5600, 120, IEEE80211_CH_PASSIVE_ONLY},
+	       {5620, 124, IEEE80211_CH_PASSIVE_ONLY},
+	       {5640, 128, IEEE80211_CH_PASSIVE_ONLY},
+	       {5660, 132, IEEE80211_CH_PASSIVE_ONLY},
+	       {5680, 136, IEEE80211_CH_PASSIVE_ONLY},
+	       {5700, 140, IEEE80211_CH_PASSIVE_ONLY},
+	       {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
+	       {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
+	       {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
+	       {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
+	       {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
+	 },
+
+	{			/* Europe */
+	 "ZZL",
+	 .bg_channels = 11,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}},
+	 .a_channels = 13,
+	 .a = {{5180, 36, IEEE80211_CH_PASSIVE_ONLY},
+	       {5200, 40, IEEE80211_CH_PASSIVE_ONLY},
+	       {5220, 44, IEEE80211_CH_PASSIVE_ONLY},
+	       {5240, 48, IEEE80211_CH_PASSIVE_ONLY},
+	       {5260, 52, IEEE80211_CH_PASSIVE_ONLY},
+	       {5280, 56, IEEE80211_CH_PASSIVE_ONLY},
+	       {5300, 60, IEEE80211_CH_PASSIVE_ONLY},
+	       {5320, 64, IEEE80211_CH_PASSIVE_ONLY},
+	       {5745, 149, IEEE80211_CH_PASSIVE_ONLY},
+	       {5765, 153, IEEE80211_CH_PASSIVE_ONLY},
+	       {5785, 157, IEEE80211_CH_PASSIVE_ONLY},
+	       {5805, 161, IEEE80211_CH_PASSIVE_ONLY},
+	       {5825, 165, IEEE80211_CH_PASSIVE_ONLY}},
+	 }
 };
 
 #define MAX_HW_RESTARTS 5
 static int ipw_up(struct ipw_priv *priv)
 {
-	int rc, i;
+	int rc, i, j;
 
 	if (priv->status & STATUS_EXIT_PENDING)
 		return -EIO;
@@ -10414,9 +10642,20 @@ static int ipw_up(struct ipw_priv *priv)
 			eeprom_parse_mac(priv, priv->mac_addr);
 		memcpy(priv->net_dev->dev_addr, priv->mac_addr, ETH_ALEN);
 
-		memcpy(priv->country, &priv->eeprom[EEPROM_COUNTRY_CODE], 3);
-		priv->country[3] = '\0';
-		ieee80211_set_geo(priv->ieee, &ipw_geo);
+		for (j = 0; j < ARRAY_SIZE(ipw_geos); j++) {
+			if (!memcmp(&priv->eeprom[EEPROM_COUNTRY_CODE],
+				    ipw_geos[j].name, 3))
+				break;
+		}
+		if (j == ARRAY_SIZE(ipw_geos))
+			j = 0;
+		if (ieee80211_set_geo(priv->ieee, &ipw_geos[j])) {
+			IPW_WARNING("Could not set geography.");
+			return 0;
+		}
+
+		IPW_DEBUG_INFO("Geography %03d [%s] detected.\n",
+			       j, priv->ieee->geo.name);
 
 		if (priv->status & STATUS_RF_KILL_SW) {
 			IPW_WARNING("Radio disabled by module parameter.\n");
---
0.99.8.GIT


--- NEW FILE 2929-Workaround-kernel-BUG_ON-panic-caused-by-unexpected-duplicate-packets.txt ---
Subject: [PATCH] Workaround kernel BUG_ON panic caused by unexpected duplicate packets.
From: Zhu Yi <chuyee at debian.sh.intel.com>
Date: 1123233455 +0800

Signed-off-by: Zhu Yi <yi.zhu at intel.com>

---

 drivers/net/wireless/ipw2200.c |    6 ++++--
 1 files changed, 4 insertions(+), 2 deletions(-)

applies-to: d3d36c3f1c7d872db0ea583ed89470613ebe27d5
87b016cb64b267a6f791494a4cfd84e84e022ebb
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 6e79ae2..483993a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -7696,7 +7696,6 @@ static inline int is_network_packet(stru
 static inline int is_duplicate_packet(struct ipw_priv *priv,
 				      struct ieee80211_hdr_4addr *header)
 {
-	u16 fc = le16_to_cpu(header->frame_ctl);
 	u16 sc = le16_to_cpu(header->seq_ctl);
 	u16 seq = WLAN_GET_SEQ_SEQ(sc);
 	u16 frag = WLAN_GET_SEQ_FRAG(sc);
@@ -7760,7 +7759,10 @@ static inline int is_duplicate_packet(st
 	return 0;
 
       drop:
-	BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
+	/* Comment this line now since we observed the card receives
+	 * duplicate packets but the FCTL_RETRY bit is not set in the
+	 * IBSS mode with fragmentation enabled.
+	 BUG_ON(!(le16_to_cpu(header->frame_ctl) & IEEE80211_FCTL_RETRY)); */
 	return 1;
 }
 
---
0.99.8.GIT


--- NEW FILE 2930-Disable-host-fragmentation-in-open-mode-since-IPW2200-2915-hardware.txt ---
Subject: [PATCH] Disable host fragmentation in open mode since IPW2200/2915 hardware
From: Zhu Yi <yi.zhu at intel.com>
Date: 1123233640 +0800
support hardware fragmentation.

Signed-off-by: Zhu Yi <yi.zhu at intel.com>

---

 drivers/net/wireless/ipw2200.c |    3 +++
 1 files changed, 3 insertions(+), 0 deletions(-)

applies-to: ed62edcd2685229da636be3e605a309e89759607
e402c9374112aaf1fc5796013dc3040ebb3954ca
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 483993a..f8dac52 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8069,6 +8069,9 @@ static int ipw_sw_reset(struct ipw_priv 
 	}
 	IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
 
+	/* IPW2200/2915 is abled to do hardware fragmentation. */
+	priv->ieee->host_open_frag = 0;
+
 	if ((priv->pci_dev->device == 0x4223) ||
 	    (priv->pci_dev->device == 0x4224)) {
 		if (init)
---
0.99.8.GIT


--- NEW FILE 2931-Bug-792-Fix-WPA-PSK-AES-both-for-Dipw-and-Dwext.txt ---
Subject: [PATCH] [Bug 792] Fix WPA-PSK AES both for -Dipw and -Dwext.
From: Zhu Yi <yi.zhu at intel.com>
Date: 1123233776 +0800

Signed-off-by: Zhu Yi <yi.zhu at intel.com>

---

 drivers/net/wireless/ipw2200.c |  141 +++++++++++++++++++++++++++++++++++-----
 1 files changed, 125 insertions(+), 16 deletions(-)

applies-to: c4c3aa9d0ae2e9b773b2421ef221bb54f0c677a7
1fbfea549f07f1f7afd436f1e45b25437f0172c2
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index f8dac52..c6da5f5 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -5557,6 +5557,55 @@ static void ipw_send_wep_keys(struct ipw
 	}
 }
 
+static void ipw_set_hw_decrypt_unicast(struct ipw_priv *priv, int level)
+{
+	if (priv->ieee->host_encrypt)
+		return;
+
+	switch (level) {
+	case SEC_LEVEL_3:
+		priv->sys_config.disable_unicast_decryption = 0;
+		priv->ieee->host_decrypt = 0;
+		break;
+	case SEC_LEVEL_2:
+		priv->sys_config.disable_unicast_decryption = 1;
+		priv->ieee->host_decrypt = 1;
+		break;
+	case SEC_LEVEL_1:
+		priv->sys_config.disable_unicast_decryption = 0;
+		priv->ieee->host_decrypt = 0;
+		break;
+	case SEC_LEVEL_0:
+		priv->sys_config.disable_unicast_decryption = 1;
+		break;
+	default:
+		break;
+	}
+}
+
+static void ipw_set_hw_decrypt_multicast(struct ipw_priv *priv, int level)
+{
+	if (priv->ieee->host_encrypt)
+		return;
+
+	switch (level) {
+	case SEC_LEVEL_3:
+		priv->sys_config.disable_multicast_decryption = 0;
+		break;
+	case SEC_LEVEL_2:
+		priv->sys_config.disable_multicast_decryption = 1;
+		break;
+	case SEC_LEVEL_1:
+		priv->sys_config.disable_multicast_decryption = 0;
+		break;
+	case SEC_LEVEL_0:
+		priv->sys_config.disable_multicast_decryption = 1;
+		break;
+	default:
+		break;
+	}
+}
+
 static void ipw_set_hwcrypto_keys(struct ipw_priv *priv)
 {
 	switch (priv->ieee->sec.level) {
@@ -5567,33 +5616,23 @@ static void ipw_set_hwcrypto_keys(struct
 					    priv->ieee->sec.active_key);
 
 		ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
-		priv->sys_config.disable_unicast_decryption = 0;
-		priv->sys_config.disable_multicast_decryption = 0;
-		priv->ieee->host_decrypt = 0;
 		break;
 	case SEC_LEVEL_2:
 		if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
 			ipw_send_tgi_tx_key(priv,
 					    DCT_FLAG_EXT_SECURITY_TKIP,
 					    priv->ieee->sec.active_key);
-
-		priv->sys_config.disable_unicast_decryption = 1;
-		priv->sys_config.disable_multicast_decryption = 1;
-		priv->ieee->host_decrypt = 1;
 		break;
 	case SEC_LEVEL_1:
 		ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
-		priv->sys_config.disable_unicast_decryption = 0;
-		priv->sys_config.disable_multicast_decryption = 0;
-		priv->ieee->host_decrypt = 0;
 		break;
 	case SEC_LEVEL_0:
-		priv->sys_config.disable_unicast_decryption = 1;
-		priv->sys_config.disable_multicast_decryption = 1;
-		break;
 	default:
 		break;
 	}
+
+	ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
+	ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
 }
 
 static void ipw_adhoc_check(void *data)
@@ -6185,12 +6224,31 @@ static int ipw_wpa_mlme(struct net_devic
 	return ret;
 }
 
+static int ipw_wpa_ie_cipher2level(u8 cipher)
+{
+	switch (cipher) {
+	case 4:		/* CCMP */
+		return SEC_LEVEL_3;
+	case 2:		/* TKIP */
+		return SEC_LEVEL_2;
+	case 5:		/* WEP104 */
+	case 1:		/* WEP40 */
+		return SEC_LEVEL_1;
+	case 0:		/* NONE */
+		return SEC_LEVEL_0;
+	default:
+		return -1;
+	}
+}
+
 static int ipw_wpa_set_wpa_ie(struct net_device *dev,
 			      struct ipw_param *param, int plen)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_device *ieee = priv->ieee;
 	u8 *buf;
+	u8 *ptk, *gtk;
+	int level;
 
 	if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
 	    (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
@@ -6209,8 +6267,35 @@ static int ipw_wpa_set_wpa_ie(struct net
 		kfree(ieee->wpa_ie);
 		ieee->wpa_ie = NULL;
 		ieee->wpa_ie_len = 0;
+		goto done;
+	}
+
+	if (priv->ieee->host_encrypt)
+		goto done;
+
+	/* HACK: Parse wpa_ie here to get pairwise suite, otherwise
+	 * we need to change driver_ipw.c from wpa_supplicant. This
+	 * is OK since -Dipw is deprecated. The -Dwext driver has a
+	 * clean way to handle this. */
+	gtk = ptk = (u8 *) ieee->wpa_ie;
+	if (ieee->wpa_ie[0] == 0x30) {	/* RSN IE */
+		gtk += 4 + 3;
+		ptk += 4 + 4 + 2 + 3;
+	} else {		/* WPA IE */
+		gtk += 8 + 3;
+		ptk += 8 + 4 + 2 + 3;
 	}
 
+	if (ptk - (u8 *) ieee->wpa_ie > ieee->wpa_ie_len)
+		return -EINVAL;
+
+	level = ipw_wpa_ie_cipher2level(*gtk);
+	ipw_set_hw_decrypt_multicast(priv, level);
+
+	level = ipw_wpa_ie_cipher2level(*ptk);
+	ipw_set_hw_decrypt_unicast(priv, level);
+
+      done:
 	ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
 	return 0;
 }
@@ -6510,6 +6595,23 @@ static int ipw_wx_get_genie(struct net_d
 	return err;
 }
 
+static int wext_cipher2level(int cipher)
+{
+	switch (cipher) {
+	case IW_AUTH_CIPHER_NONE:
+		return SEC_LEVEL_0;
+	case IW_AUTH_CIPHER_WEP40:
+	case IW_AUTH_CIPHER_WEP104:
+		return SEC_LEVEL_1;
+	case IW_AUTH_CIPHER_TKIP:
+		return SEC_LEVEL_2;
+	case IW_AUTH_CIPHER_CCMP:
+		return SEC_LEVEL_3;
+	default:
+		return -1;
+	}
+}
+
 /* SIOCSIWAUTH */
 static int ipw_wx_set_auth(struct net_device *dev,
 			   struct iw_request_info *info,
@@ -6524,8 +6626,15 @@ static int ipw_wx_set_auth(struct net_de
 
 	switch (param->flags & IW_AUTH_INDEX) {
 	case IW_AUTH_WPA_VERSION:
+		break;
 	case IW_AUTH_CIPHER_PAIRWISE:
+		ipw_set_hw_decrypt_unicast(priv,
+					   wext_cipher2level(param->value));
+		break;
 	case IW_AUTH_CIPHER_GROUP:
+		ipw_set_hw_decrypt_multicast(priv,
+					     wext_cipher2level(param->value));
+		break;
 	case IW_AUTH_KEY_MGMT:
 		/*
 		 * ipw2200 does not use these parameters
@@ -10256,11 +10365,11 @@ static void shim__set_security(struct ne
 		priv->ieee->sec.level = sec->level;
 		priv->ieee->sec.flags |= SEC_LEVEL;
 		priv->status |= STATUS_SECURITY_UPDATED;
-
-		if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
-			ipw_set_hwcrypto_keys(priv);
 	}
 
+	if (!priv->ieee->host_encrypt && (sec->flags & SEC_ENCRYPT))
+		ipw_set_hwcrypto_keys(priv);
+
 	/* To match current functionality of ipw2100 (which works well w/
 	 * various supplicants, we don't force a disassociate if the
 	 * privacy capability changes ... */
---
0.99.8.GIT


--- NEW FILE 2932-Fixes-the-ad-hoc-network-WEP-key-list-issue.txt ---
Subject: [PATCH] Fixes the ad-hoc network WEP key list issue.
From: Hong Liu <hong.liu at intel.com>
Date: 1123233950 +0800

If we configure the wep keys after creating the ibss network, the
beacons of this network will not show correctly (it still shows "key
off" in iwlist scan report). This is because we don't update the
beacon info in firmware.

Signed-off-by: Hong Liu <hong.liu at intel.com>
Signed-off-by: Zhu Yi <yi.zhu at intel.com>

---

 drivers/net/wireless/ipw2200.c |   10 +++++++++-
 1 files changed, 9 insertions(+), 1 deletions(-)

applies-to: 96dced82fc405eab36695e1f7568c4c77fc77324
caeff81b4e6479884f3cd2ced526bebd4f0c5eff
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index c6da5f5..626e78a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -9169,11 +9169,19 @@ static int ipw_wx_set_encode(struct net_
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	int ret;
+	u32 cap = priv->capability;
 
 	down(&priv->sem);
 	ret = ieee80211_wx_set_encode(priv->ieee, info, wrqu, key);
-	up(&priv->sem);
 
+	/* In IBSS mode, we need to notify the firmware to update
+	 * the beacon info after we changed the capability. */
+	if (cap != priv->capability &&
+	    priv->ieee->iw_mode == IW_MODE_ADHOC &&
+	    priv->status & STATUS_ASSOCIATED)
+		ipw_disassociate(priv);
+
+	up(&priv->sem);
 	return ret;
 }
 
---
0.99.8.GIT


--- NEW FILE 2933-Bug-701-Fix-a-misuse-of-ieee-mode-with-ieee-iw_mode.txt ---
Subject: [PATCH] [Bug 701] Fix a misuse of ieee->mode with ieee->iw_mode.
From: Zhu Yi <yi.zhu at intel.com>
Date: 1123234011 +0800

Signed-off-by: Zhu Yi <yi.zhu at intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: f5b3a452d519d904acd16f30ef4a5c973635ecbd
0ece35b557c5097c90df9e8fbf47e4da46377df1
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 626e78a..2633e0d 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8223,7 +8223,7 @@ static int ipw_sw_reset(struct ipw_priv 
 	priv->power_mode = IPW_POWER_AC;
 	priv->tx_power = IPW_TX_POWER_DEFAULT;
 
-	return old_mode == priv->ieee->mode;
+	return old_mode == priv->ieee->iw_mode;
 }
 
 /*
---
0.99.8.GIT


--- NEW FILE 2934-Fix-ipw_wx_get_txpow-shows-wrong-disabled-value.txt ---
Subject: [PATCH] Fix ipw_wx_get_txpow shows wrong disabled value.
From: Zhu Yi <yi.zhu at intel.com>
Date: 1123728557 +0800

Signed-off-by: Zhu Yi <yi.zhu at intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 36a6b5de7924cbd2fe007fe5bf70074a906786ff
22501c8ed70398178e8c8d55e65da97b7e7fb610
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 2633e0d..105b114 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8957,7 +8957,7 @@ static int ipw_wx_get_txpow(struct net_d
 	up(&priv->sem);
 
 	IPW_DEBUG_WX("GET TX Power -> %s %d \n",
-		     wrqu->power.disabled ? "ON" : "OFF", wrqu->power.value);
+		     wrqu->power.disabled ? "OFF" : "ON", wrqu->power.value);
 
 	return 0;
 }
---
0.99.8.GIT


--- NEW FILE 2935-Fix-firmware-error-when-setting-tx_power.txt ---
Subject: [PATCH] Fix firmware error when setting tx_power.
From: Zhu Yi <yi.zhu at intel.com>
Date: 1123742373 +0800

Signed-off-by: Zhu Yi <yi.zhu at intel.com>

---

 drivers/net/wireless/ipw2200.c |  131 +++++++++++++++++-----------------------
 1 files changed, 55 insertions(+), 76 deletions(-)

applies-to: e74d5a23135d98c890b7ebd9c79d773071d960ea
6de9f7f27defe6f1a2d33d0b78af6b1a0ad18330
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 105b114..f825aa4 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -2084,6 +2084,50 @@ static int ipw_send_tx_power(struct ipw_
 	return 0;
 }
 
+static int ipw_set_tx_power(struct ipw_priv *priv)
+{
+	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	struct ipw_tx_power tx_power;
+	s8 max_power;
+	int i;
+
+	memset(&tx_power, 0, sizeof(tx_power));
+
+	/* configure device for 'G' band */
+	tx_power.ieee_mode = IPW_G_MODE;
+	tx_power.num_channels = geo->bg_channels;
+	for (i = 0; i < geo->bg_channels; i++) {
+		max_power = geo->bg[i].max_power;
+		tx_power.channels_tx_power[i].channel_number =
+		    geo->bg[i].channel;
+		tx_power.channels_tx_power[i].tx_power = max_power ?
+		    min(max_power, priv->tx_power) : priv->tx_power;
+	}
+	if (ipw_send_tx_power(priv, &tx_power))
+		return -EIO;
+
+	/* configure device to also handle 'B' band */
+	tx_power.ieee_mode = IPW_B_MODE;
+	if (ipw_send_tx_power(priv, &tx_power))
+		return -EIO;
+
+	/* configure device to also handle 'A' band */
+	if (priv->ieee->abg_true) {
+		tx_power.ieee_mode = IPW_A_MODE;
+		tx_power.num_channels = geo->a_channels;
+		for (i = 0; i < tx_power.num_channels; i++) {
+			max_power = geo->a[i].max_power;
+			tx_power.channels_tx_power[i].channel_number =
+			    geo->a[i].channel;
+			tx_power.channels_tx_power[i].tx_power = max_power ?
+			    min(max_power, priv->tx_power) : priv->tx_power;
+		}
+		if (ipw_send_tx_power(priv, &tx_power))
+			return -EIO;
+	}
+	return 0;
+}
+
 static int ipw_send_rts_threshold(struct ipw_priv *priv, u16 rts)
 {
 	struct ipw_rts_threshold rts_threshold = {
@@ -8869,79 +8913,33 @@ static int ipw_wx_set_txpow(struct net_d
 			    union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
-	struct ipw_tx_power tx_power;
-	int i;
+	int err = 0;
 
 	down(&priv->sem);
 	if (ipw_radio_kill_sw(priv, wrqu->power.disabled)) {
-		up(&priv->sem);
-		return -EINPROGRESS;
+		err = -EINPROGRESS;
+		goto out;
 	}
 
 	if (!wrqu->power.fixed)
 		wrqu->power.value = IPW_TX_POWER_DEFAULT;
 
 	if (wrqu->power.flags != IW_TXPOW_DBM) {
-		up(&priv->sem);
-		return -EINVAL;
+		err = -EINVAL;
+		goto out;
 	}
 
 	if ((wrqu->power.value > IPW_TX_POWER_MAX) ||
 	    (wrqu->power.value < IPW_TX_POWER_MIN)) {
-		up(&priv->sem);
-		return -EINVAL;
+		err = -EINVAL;
+		goto out;
 	}
 
 	priv->tx_power = wrqu->power.value;
-
-	memset(&tx_power, 0, sizeof(tx_power));
-
-	/* configure device for 'G' band */
-	tx_power.ieee_mode = IPW_G_MODE;
-	tx_power.num_channels = geo->bg_channels;
-	for (i = 0; i < geo->bg_channels; i++) {
-		int max_power = geo->bg[i].max_power;
-
-		tx_power.channels_tx_power[i].channel_number = i + 1;
-		if (max_power != 0 && priv->tx_power > max_power)
-			tx_power.channels_tx_power[i].tx_power = max_power;
-		else
-			tx_power.channels_tx_power[i].tx_power = priv->tx_power;
-	}
-	if (ipw_send_tx_power(priv, &tx_power))
-		goto error;
-
-	/* configure device to also handle 'B' band */
-	tx_power.ieee_mode = IPW_B_MODE;
-	if (ipw_send_tx_power(priv, &tx_power))
-		goto error;
-
-	/* configure device to also handle 'A' band */
-	if (priv->ieee->abg_true) {
-		tx_power.ieee_mode = IPW_A_MODE;
-		tx_power.num_channels = geo->a_channels;
-		for (i = 0; i < geo->a_channels; i++) {
-			int max_power = geo->a[i].max_power;
-
-			tx_power.channels_tx_power[i].channel_number = i + 1;
-			if (max_power != 0 && priv->tx_power > max_power)
-				tx_power.channels_tx_power[i].tx_power =
-				    max_power;
-			else
-				tx_power.channels_tx_power[i].tx_power =
-				    priv->tx_power;
-		}
-		if (ipw_send_tx_power(priv, &tx_power))
-			goto error;
-	}
-
-	up(&priv->sem);
-	return 0;
-
-      error:
+	err = ipw_set_tx_power(priv);
+      out:
 	up(&priv->sem);
-	return -EIO;
+	return err;
 }
 
 static int ipw_wx_get_txpow(struct net_device *dev,
@@ -10426,29 +10424,10 @@ static int init_supported_rates(struct i
 
 static int ipw_config(struct ipw_priv *priv)
 {
-	int i;
-	struct ipw_tx_power tx_power;
-
-	memset(&priv->sys_config, 0, sizeof(priv->sys_config));
-	memset(&tx_power, 0, sizeof(tx_power));
-
 	/* This is only called from ipw_up, which resets/reloads the firmware
 	   so, we don't need to first disable the card before we configure
 	   it */
-
-	/* configure device for 'G' band */
-	tx_power.ieee_mode = IPW_G_MODE;
-	tx_power.num_channels = 11;
-	for (i = 0; i < 11; i++) {
-		tx_power.channels_tx_power[i].channel_number = i + 1;
-		tx_power.channels_tx_power[i].tx_power = priv->tx_power;
-	}
-	if (ipw_send_tx_power(priv, &tx_power))
-		goto error;
-
-	/* configure device to also handle 'B' band */
-	tx_power.ieee_mode = IPW_B_MODE;
-	if (ipw_send_tx_power(priv, &tx_power))
+	if (ipw_set_tx_power(priv))
 		goto error;
 
 	/* initialize adapter address */
---
0.99.8.GIT


--- NEW FILE 2936-Modified-ipw_config-and-STATUS_INIT-setting-to-correct-race-condition.txt ---
Subject: [PATCH] Modified ipw_config and STATUS_INIT setting to correct race condition
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1123856224 -0500
with request_scan being called before initialized if invoked from
insmod, resulting in no association occurring during boot until iwlist
scan is run.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   29 +++++++++++++++--------------
 1 files changed, 15 insertions(+), 14 deletions(-)

applies-to: b30d488ffce4501c659cce7b9e43c82ebbdbddd3
e666619e232308c8ee2aba6b87f28ad26b38d905
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index f825aa4..6e862c2 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -10465,9 +10465,17 @@ static int ipw_config(struct ipw_priv *p
 	if (ipw_send_host_complete(priv))
 		goto error;
 
-	/* If configured to try and auto-associate, kick off a scan */
-	if (priv->config & CFG_ASSOCIATE)
-		queue_work(priv->workqueue, &priv->request_scan);
+	priv->status |= STATUS_INIT;
+
+	ipw_led_init(priv);
+	ipw_led_radio_on(priv);
+	priv->notif_missed_beacons = 0;
+
+	/* Set hardware WEP key if it is configured. */
+	if ((priv->capability & CAP_PRIVACY_ON) &&
+	    (priv->ieee->sec.level == SEC_LEVEL_1) &&
+	    !(priv->ieee->host_encrypt || priv->ieee->host_decrypt))
+		ipw_set_hwcrypto_keys(priv);
 
 	return 0;
 
@@ -10773,17 +10781,10 @@ static int ipw_up(struct ipw_priv *priv)
 		rc = ipw_config(priv);
 		if (!rc) {
 			IPW_DEBUG_INFO("Configured device on count %i\n", i);
-			ipw_led_init(priv);
-			ipw_led_radio_on(priv);
-			priv->notif_missed_beacons = 0;
-			priv->status |= STATUS_INIT;
-
-			/* Set hardware WEP key if it is configured. */
-			if ((priv->capability & CAP_PRIVACY_ON) &&
-			    (priv->ieee->sec.level == SEC_LEVEL_1) &&
-			    !(priv->ieee->host_encrypt ||
-			      priv->ieee->host_decrypt))
-				ipw_set_hwcrypto_keys(priv);
+
+			/* If configure to try and auto-associate, kick
+			 * off a scan. */
+			queue_work(priv->workqueue, &priv->request_scan);
 
 			return 0;
 		}
---
0.99.8.GIT


--- NEW FILE 2937-Switched-firmware-error-dumping-so-that-it-will-capture-a-log-available.txt ---
Subject: [PATCH] Switched firmware error dumping so that it will capture a log available
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1123857392 -0500
via sysfs even if debugging disabled.  When a firmware error is
captured, it will be dumped to the kernel log (if debug enabled) and
captured in memory to be retrieved via sysfs.

If an error has already been captured, subsequent errors will be
dropped.

The existing error can be cleared by writing to the error log entry.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |  253 ++++++++++++++++++++++++++++------------
 drivers/net/wireless/ipw2200.h |   30 +++++
 2 files changed, 205 insertions(+), 78 deletions(-)

applies-to: 37cb616367595bb95c456ed938ff78c8db87846a
b39860c60b135ef16c1c16a3e2a757ff8070c5ad
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 6e862c2..a3283ca 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -428,6 +428,7 @@ static inline void ipw_disable_interrupt
 	ipw_write32(priv, IPW_INTA_MASK_R, ~IPW_INTA_MASK_ALL);
 }
 
+#ifdef CONFIG_IPW_DEBUG
 static char *ipw_error_desc(u32 val)
 {
 	switch (val) {
@@ -466,56 +467,35 @@ static char *ipw_error_desc(u32 val)
 	}
 }
 
-static void ipw_dump_nic_error_log(struct ipw_priv *priv)
+static void ipw_dump_error_log(struct ipw_priv *priv,
+			       struct ipw_fw_error *error)
 {
-	u32 desc, time, blink1, blink2, ilink1, ilink2, idata, i, count, base;
+	u32 i;
 
-	base = ipw_read32(priv, IPWSTATUS_ERROR_LOG);
-	count = ipw_read_reg32(priv, base);
+	if (!error) {
+		IPW_ERROR("Error allocating and capturing error log.  "
+			  "Nothing to dump.\n");
+		return;
+	}
 
-	if (ERROR_START_OFFSET <= count * ERROR_ELEM_SIZE) {
-		IPW_ERROR("Start IPW Error Log Dump:\n");
-		IPW_ERROR("Status: 0x%08X, Config: %08X\n",
-			  priv->status, priv->config);
-	}
-
-	for (i = ERROR_START_OFFSET;
-	     i <= count * ERROR_ELEM_SIZE; i += ERROR_ELEM_SIZE) {
-		desc = ipw_read_reg32(priv, base + i);
-		time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
-		blink1 = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
-		blink2 = ipw_read_reg32(priv, base + i + 3 * sizeof(u32));
-		ilink1 = ipw_read_reg32(priv, base + i + 4 * sizeof(u32));
-		ilink2 = ipw_read_reg32(priv, base + i + 5 * sizeof(u32));
-		idata = ipw_read_reg32(priv, base + i + 6 * sizeof(u32));
+	IPW_ERROR("Start IPW Error Log Dump:\n");
+	IPW_ERROR("Status: 0x%08X, Config: %08X\n",
+		  error->status, error->config);
 
+	for (i = 0; i < error->elem_len; i++)
 		IPW_ERROR("%s %i 0x%08x  0x%08x  0x%08x  0x%08x  0x%08x\n",
-			  ipw_error_desc(desc), time, blink1, blink2,
-			  ilink1, ilink2, idata);
-	}
+			  ipw_error_desc(error->elem[i].desc),
+			  error->elem[i].time,
+			  error->elem[i].blink1,
+			  error->elem[i].blink2,
+			  error->elem[i].link1,
+			  error->elem[i].link2, error->elem[i].data);
+	for (i = 0; i < error->log_len; i++)
+		IPW_ERROR("%i\t0x%08x\t%i\n",
+			  error->log[i].time,
+			  error->log[i].event, error->log[i].data);
 }
-
-static void ipw_dump_nic_event_log(struct ipw_priv *priv)
-{
-	u32 ev, time, data, i, count, base;
-
-	base = ipw_read32(priv, IPW_EVENT_LOG);
-	count = ipw_read_reg32(priv, base);
-
-	if (EVENT_START_OFFSET <= count * EVENT_ELEM_SIZE)
-		IPW_ERROR("Start IPW Event Log Dump:\n");
-
-	for (i = EVENT_START_OFFSET;
-	     i <= count * EVENT_ELEM_SIZE; i += EVENT_ELEM_SIZE) {
-		ev = ipw_read_reg32(priv, base + i);
-		time = ipw_read_reg32(priv, base + i + 1 * sizeof(u32));
-		data = ipw_read_reg32(priv, base + i + 2 * sizeof(u32));
-
-#ifdef CONFIG_IPW_DEBUG
-		IPW_ERROR("%i\t0x%08x\t%i\n", time, data, ev);
 #endif
-	}
-}
 
 static inline int ipw_is_init(struct ipw_priv *priv)
 {
@@ -1058,6 +1038,130 @@ static ssize_t store_debug_level(struct 
 static DRIVER_ATTR(debug_level, S_IWUSR | S_IRUGO,
 		   show_debug_level, store_debug_level);
 
+static inline u32 ipw_get_event_log_len(struct ipw_priv *priv)
+{
+	return ipw_read_reg32(priv, ipw_read32(priv, IPW_EVENT_LOG));
+}
+
+static void ipw_capture_event_log(struct ipw_priv *priv,
+				  u32 log_len, struct ipw_event *log)
+{
+	u32 base;
+
+	if (log_len) {
+		base = ipw_read32(priv, IPW_EVENT_LOG);
+		ipw_read_indirect(priv, base + sizeof(base) + sizeof(u32),
+				  (u8 *) log, sizeof(*log) * log_len);
+	}
+}
+
+static struct ipw_fw_error *ipw_alloc_error_log(struct ipw_priv *priv)
+{
+	struct ipw_fw_error *error;
+	u32 log_len = ipw_get_event_log_len(priv);
+	u32 base = ipw_read32(priv, IPW_ERROR_LOG);
+	u32 elem_len = ipw_read_reg32(priv, base);
+
+	error = kmalloc(sizeof(*error) +
+			sizeof(*error->elem) * elem_len +
+			sizeof(*error->log) * log_len, GFP_ATOMIC);
+	if (!error) {
+		IPW_ERROR("Memory allocation for firmware error log "
+			  "failed.\n");
+		return NULL;
+	}
+	error->status = priv->status;
+	error->config = priv->config;
+	error->elem_len = elem_len;
+	error->log_len = log_len;
+	error->elem = (struct ipw_error_elem *)error->payload;
+	error->log = (struct ipw_event *)(error->elem +
+					  (sizeof(*error->elem) * elem_len));
+
+	ipw_capture_event_log(priv, log_len, error->log);
+
+	if (elem_len)
+		ipw_read_indirect(priv, base + sizeof(base), (u8 *) error->elem,
+				  sizeof(*error->elem) * elem_len);
+
+	return error;
+}
+
+static void ipw_free_error_log(struct ipw_fw_error *error)
+{
+	if (error)
+		kfree(error);
+}
+
+static ssize_t show_event_log(struct device *d,
+			      struct device_attribute *attr, char *buf)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	u32 log_len = ipw_get_event_log_len(priv);
+	struct ipw_event log[log_len];
+	u32 len = 0, i;
+
+	ipw_capture_event_log(priv, log_len, log);
+
+	len += snprintf(buf + len, PAGE_SIZE - len, "%08X", log_len);
+	for (i = 0; i < log_len; i++)
+		len += snprintf(buf + len, PAGE_SIZE - len,
+				"\n%08X%08X%08X",
+				log[i].time, log[i].event, log[i].data);
+	len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+	return len;
+}
+
+static DEVICE_ATTR(event_log, S_IRUGO, show_event_log, NULL);
+
+static ssize_t show_error(struct device *d,
+			  struct device_attribute *attr, char *buf)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	u32 len = 0, i;
+	if (!priv->error)
+		return 0;
+	len += snprintf(buf + len, PAGE_SIZE - len,
+			"%08X%08X%08X",
+			priv->error->status,
+			priv->error->config, priv->error->elem_len);
+	for (i = 0; i < priv->error->elem_len; i++)
+		len += snprintf(buf + len, PAGE_SIZE - len,
+				"\n%08X%08X%08X%08X%08X%08X%08X",
+				priv->error->elem[i].time,
+				priv->error->elem[i].desc,
+				priv->error->elem[i].blink1,
+				priv->error->elem[i].blink2,
+				priv->error->elem[i].link1,
+				priv->error->elem[i].link2,
+				priv->error->elem[i].data);
+
+	len += snprintf(buf + len, PAGE_SIZE - len,
+			"\n%08X", priv->error->log_len);
+	for (i = 0; i < priv->error->log_len; i++)
+		len += snprintf(buf + len, PAGE_SIZE - len,
+				"\n%08X%08X%08X",
+				priv->error->log[i].time,
+				priv->error->log[i].event,
+				priv->error->log[i].data);
+	len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+	return len;
+}
+
+static ssize_t clear_error(struct device *d,
+			   struct device_attribute *attr,
+			   const char *buf, size_t count)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	if (priv->error) {
+		ipw_free_error_log(priv->error);
+		priv->error = NULL;
+	}
+	return count;
+}
+
+static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
+
 static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
 			     char *buf)
 {
@@ -1163,34 +1267,6 @@ static ssize_t show_nic_type(struct devi
 
 static DEVICE_ATTR(nic_type, S_IRUGO, show_nic_type, NULL);
 
-static ssize_t dump_error_log(struct device *d,
-			      struct device_attribute *attr, const char *buf,
-			      size_t count)
-{
-	char *p = (char *)buf;
-
-	if (p[0] == '1')
-		ipw_dump_nic_error_log((struct ipw_priv *)d->driver_data);
-
-	return strnlen(buf, count);
-}
-
-static DEVICE_ATTR(dump_errors, S_IWUSR, NULL, dump_error_log);
-
-static ssize_t dump_event_log(struct device *d,
-			      struct device_attribute *attr, const char *buf,
-			      size_t count)
-{
-	char *p = (char *)buf;
-
-	if (p[0] == '1')
-		ipw_dump_nic_event_log((struct ipw_priv *)d->driver_data);
-
-	return strnlen(buf, count);
-}
-
-static DEVICE_ATTR(dump_events, S_IWUSR, NULL, dump_event_log);
-
 static ssize_t show_ucode_version(struct device *d,
 				  struct device_attribute *attr, char *buf)
 {
@@ -1614,12 +1690,30 @@ static void ipw_irq_tasklet(struct ipw_p
 
 	if (inta & IPW_INTA_BIT_FATAL_ERROR) {
 		IPW_ERROR("Firmware error detected.  Restarting.\n");
+		if (priv->error) {
+			IPW_ERROR("Sysfs 'error' log already exists.\n");
 #ifdef CONFIG_IPW_DEBUG
-		if (ipw_debug_level & IPW_DL_FW_ERRORS) {
-			ipw_dump_nic_error_log(priv);
-			ipw_dump_nic_event_log(priv);
-		}
+			if (ipw_debug_level & IPW_DL_FW_ERRORS) {
+				struct ipw_fw_error *error =
+				    ipw_alloc_error_log(priv);
+				ipw_dump_error_log(priv, error);
+				if (error)
+					ipw_free_error_log(error);
+			}
+#endif
+		} else {
+			priv->error = ipw_alloc_error_log(priv);
+			if (priv->error)
+				IPW_ERROR("Sysfs 'error' log captured.\n");
+			else
+				IPW_ERROR("Error allocating sysfs 'error' "
+					  "log.\n");
+#ifdef CONFIG_IPW_DEBUG
+			if (ipw_debug_level & IPW_DL_FW_ERRORS)
+				ipw_dump_error_log(priv, priv->error);
 #endif
+		}
+
 		/* XXX: If hardware encryption is for WPA/WPA2,
 		 * we have to notify the supplicant. */
 		if (priv->ieee->sec.encrypt) {
@@ -10958,8 +11052,8 @@ static struct attribute *ipw_sysfs_entri
 	&dev_attr_nic_type.attr,
 	&dev_attr_status.attr,
 	&dev_attr_cfg.attr,
-	&dev_attr_dump_errors.attr,
-	&dev_attr_dump_events.attr,
+	&dev_attr_error.attr,
+	&dev_attr_event_log.attr,
 	&dev_attr_eeprom_delay.attr,
 	&dev_attr_ucode_version.attr,
 	&dev_attr_rtc.attr,
@@ -11172,6 +11266,11 @@ static void ipw_pci_remove(struct pci_de
 		}
 	}
 
+	if (priv->error) {
+		ipw_free_error_log(priv->error);
+		priv->error = NULL;
+	}
+
 	free_irq(pdev->irq, priv);
 	iounmap(priv->hw_base);
 	pci_release_regions(pdev);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 9bf8aa4..9bf03ac 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1085,6 +1085,32 @@ struct ipw_ibss_seq {
 	struct list_head list;
 };
 
+struct ipw_error_elem {
+	u32 desc;
+	u32 time;
+	u32 blink1;
+	u32 blink2;
+	u32 link1;
+	u32 link2;
+	u32 data;
+};
+
+struct ipw_event {
+	u32 event;
+	u32 time;
+	u32 data;
+} __attribute__ ((packed));
+
+struct ipw_fw_error {
+	u32 status;
+	u32 config;
+	u32 elem_len;
+	u32 log_len;
+	struct ipw_error_elem *elem;
+	struct ipw_event *log;
+	u8 payload[0];
+} __attribute__ ((packed));
+
 struct ipw_priv {
 	/* ieee device used by generic ieee processing code */
 	struct ieee80211_device *ieee;
@@ -1245,6 +1271,8 @@ struct ipw_priv {
 	u32 pm_state[16];
 #endif
 
+	struct ipw_fw_error *error;
+
 	/* network state */
 
 	/* Used to pass the current INTA value from ISR to Tasklet */
@@ -1803,7 +1831,7 @@ enum {
 	IPW_ORD_TABLE_7_LAST
 };
 
-#define IPWSTATUS_ERROR_LOG     (IPW_SHARED_LOWER_BOUND + 0x410)
+#define IPW_ERROR_LOG     (IPW_SHARED_LOWER_BOUND + 0x410)
 #define IPW_EVENT_LOG     (IPW_SHARED_LOWER_BOUND + 0x414)
 #define IPW_ORDINALS_TABLE_LOWER        (IPW_SHARED_LOWER_BOUND + 0x500)
 #define IPW_ORDINALS_TABLE_0            (IPW_SHARED_LOWER_BOUND + 0x180)
---
0.99.8.GIT


--- NEW FILE 2938-Changed-all-of-the-ipw_send_cmd-calls-to-return-any-ipw_send_cmd-error.txt ---
Subject: [PATCH] Changed all of the ipw_send_cmd() calls to return any ipw_send_cmd error
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124230031 -0500
codes to the caller and changed ipw_send_cmd itself to print the error
message to the syslog indicating which command failed to be sent.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |  187 +++++++---------------------------------
 1 files changed, 34 insertions(+), 153 deletions(-)

applies-to: dde06d69fb792a0993e3a756d35a0cc9509388cf
9ddf84f6f20335ce896feb459b19c3258bbf2e96
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index a3283ca..ef10077 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1817,9 +1817,10 @@ static int ipw_send_cmd(struct ipw_priv 
 
 	spin_lock_irqsave(&priv->lock, flags);
 	if (priv->status & STATUS_HCMD_ACTIVE) {
-		IPW_ERROR("Already sending a command\n");
+		IPW_ERROR("Failed to send %s: Already sending a command.\n",
+			  get_cmd_string(cmd->cmd));
 		spin_unlock_irqrestore(&priv->lock, flags);
-		return -1;
+		return -EAGAIN;
 	}
 
 	priv->status |= STATUS_HCMD_ACTIVE;
@@ -1832,6 +1833,8 @@ static int ipw_send_cmd(struct ipw_priv 
 	rc = ipw_queue_tx_hcmd(priv, cmd->cmd, &cmd->param, cmd->len, 0);
 	if (rc) {
 		priv->status &= ~STATUS_HCMD_ACTIVE;
+		IPW_ERROR("Failed to send %s: Reason %d\n",
+			  get_cmd_string(cmd->cmd), rc);
 		spin_unlock_irqrestore(&priv->lock, flags);
 		return rc;
 	}
@@ -1844,9 +1847,8 @@ static int ipw_send_cmd(struct ipw_priv 
 	if (rc == 0) {
 		spin_lock_irqsave(&priv->lock, flags);
 		if (priv->status & STATUS_HCMD_ACTIVE) {
-			IPW_DEBUG_INFO("Command completion failed out after "
-				       "%dms.\n",
-				       1000 * (HOST_COMPLETE_TIMEOUT / HZ));
+			IPW_ERROR("Failed to send %s: Command timed out.\n",
+				  get_cmd_string(cmd->cmd));
 			priv->status &= ~STATUS_HCMD_ACTIVE;
 			spin_unlock_irqrestore(&priv->lock, flags);
 			return -EIO;
@@ -1855,7 +1857,8 @@ static int ipw_send_cmd(struct ipw_priv 
 	}
 
 	if (priv->status & STATUS_RF_KILL_HW) {
-		IPW_DEBUG_INFO("Command aborted due to RF Kill Switch\n");
+		IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
+			  get_cmd_string(cmd->cmd));
 		return -EIO;
 	}
 
@@ -1874,12 +1877,7 @@ static int ipw_send_host_complete(struct
 		return -1;
 	}
 
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send HOST_COMPLETE command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_system_config(struct ipw_priv *priv,
@@ -1896,12 +1894,7 @@ static int ipw_send_system_config(struct
 	}
 
 	memcpy(cmd.param, config, sizeof(*config));
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send SYSTEM_CONFIG command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_ssid(struct ipw_priv *priv, u8 * ssid, int len)
@@ -1917,12 +1910,7 @@ static int ipw_send_ssid(struct ipw_priv
 	}
 
 	memcpy(cmd.param, ssid, cmd.len);
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send SSID command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_adapter_address(struct ipw_priv *priv, u8 * mac)
@@ -1941,12 +1929,7 @@ static int ipw_send_adapter_address(stru
 		       priv->net_dev->name, MAC_ARG(mac));
 
 	memcpy(cmd.param, mac, ETH_ALEN);
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send ADAPTER_ADDRESS command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 /*
@@ -2011,12 +1994,7 @@ static int ipw_send_scan_request_ext(str
 	};
 
 	memcpy(cmd.param, request, sizeof(*request));
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send SCAN_REQUEST_EXT command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_scan_abort(struct ipw_priv *priv)
@@ -2031,12 +2009,7 @@ static int ipw_send_scan_abort(struct ip
 		return -1;
 	}
 
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send SCAN_ABORT command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_set_sensitivity(struct ipw_priv *priv, u16 sens)
@@ -2048,12 +2021,7 @@ static int ipw_set_sensitivity(struct ip
 	struct ipw_sensitivity_calib *calib = (struct ipw_sensitivity_calib *)
 	    &cmd.param;
 	calib->beacon_rssi_raw = sens;
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send SENSITIVITY CALIB command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_associate(struct ipw_priv *priv,
@@ -2083,12 +2051,7 @@ static int ipw_send_associate(struct ipw
 	}
 
 	memcpy(cmd.param, &tmp_associate, sizeof(*associate));
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send ASSOCIATE command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_supported_rates(struct ipw_priv *priv,
@@ -2105,12 +2068,7 @@ static int ipw_send_supported_rates(stru
 	}
 
 	memcpy(cmd.param, rates, sizeof(*rates));
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send SUPPORTED_RATES command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_set_random_seed(struct ipw_priv *priv)
@@ -2127,12 +2085,7 @@ static int ipw_set_random_seed(struct ip
 
 	get_random_bytes(&cmd.param, sizeof(u32));
 
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send SEED_NUMBER command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_card_disable(struct ipw_priv *priv, u32 phy_off)
@@ -2149,12 +2102,7 @@ static int ipw_send_card_disable(struct 
 
 	*((u32 *) & cmd.param) = phy_off;
 
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send CARD_DISABLE command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_tx_power(struct ipw_priv *priv, struct ipw_tx_power *power)
@@ -2170,12 +2118,7 @@ static int ipw_send_tx_power(struct ipw_
 	}
 
 	memcpy(cmd.param, power, sizeof(*power));
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send TX_POWER command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_set_tx_power(struct ipw_priv *priv)
@@ -2238,12 +2181,7 @@ static int ipw_send_rts_threshold(struct
 	}
 
 	memcpy(cmd.param, &rts_threshold, sizeof(rts_threshold));
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send RTS_THRESHOLD command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_frag_threshold(struct ipw_priv *priv, u16 frag)
@@ -2262,12 +2200,7 @@ static int ipw_send_frag_threshold(struc
 	}
 
 	memcpy(cmd.param, &frag_threshold, sizeof(frag_threshold));
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send FRAG_THRESHOLD command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_power_mode(struct ipw_priv *priv, u32 mode)
@@ -2297,12 +2230,7 @@ static int ipw_send_power_mode(struct ip
 		break;
 	}
 
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send POWER_MODE command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_retry_limit(struct ipw_priv *priv, u8 slimit, u8 llimit)
@@ -2322,12 +2250,7 @@ static int ipw_send_retry_limit(struct i
 	}
 
 	memcpy(cmd.param, &retry_limit, sizeof(retry_limit));
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send RETRY_LIMIT command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 /*
@@ -3608,20 +3531,6 @@ static void ipw_tx_queue_free(struct ipw
 	ipw_queue_tx_free(priv, &priv->txq[3]);
 }
 
-static void inline __maybe_wake_tx(struct ipw_priv *priv)
-{
-	if (netif_running(priv->net_dev)) {
-		switch (priv->port_type) {
-		case DCR_TYPE_MU_BSS:
-		case DCR_TYPE_MU_IBSS:
-			if (!(priv->status & STATUS_ASSOCIATED))
-				return;
-		}
-		netif_wake_queue(priv->net_dev);
-	}
-
-}
-
 static inline void ipw_create_bssid(struct ipw_priv *priv, u8 * bssid)
 {
 	/* First 3 bytes are manufacturer */
@@ -4713,8 +4622,10 @@ static int ipw_queue_tx_reclaim(struct i
 		priv->tx_packets++;
 	}
       done:
-	if (ipw_queue_space(q) > q->low_mark && qindex >= 0)
-		__maybe_wake_tx(priv);
+	if ((ipw_queue_space(q) > q->low_mark) &&
+	    (qindex >= 0) &&
+	    (priv->status & STATUS_ASSOCIATED) && netif_running(priv->net_dev))
+		netif_wake_queue(priv->net_dev);
 	used = q->first_empty - q->last_used;
 	if (used < 0)
 		used += q->n_bd;
@@ -5657,10 +5568,7 @@ static void ipw_send_tgi_tx_key(struct i
 	key->tx_counter[0] = 0;
 	key->tx_counter[1] = 0;
 
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send TGI_TX_KEY command\n");
-		return;
-	}
+	ipw_send_cmd(priv, &cmd);
 }
 
 static void ipw_send_wep_keys(struct ipw_priv *priv, int type)
@@ -5688,10 +5596,7 @@ static void ipw_send_wep_keys(struct ipw
 		key->key_size = priv->ieee->sec.key_sizes[i];
 		memcpy(key->key, priv->ieee->sec.keys[i], key->key_size);
 
-		if (ipw_send_cmd(priv, &cmd)) {
-			IPW_ERROR("failed to send WEP_KEY command\n");
-			return;
-		}
+		ipw_send_cmd(priv, &cmd);
 	}
 }
 
@@ -6249,11 +6154,7 @@ static int ipw_set_rsn_capa(struct ipw_p
 	IPW_DEBUG_HC("HOST_CMD_RSN_CAPABILITIES\n");
 
 	memcpy(cmd.param, capabilities, length);
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send HOST_CMD_RSN_CAPABILITIES command\n");
-		return -1;
-	}
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 #if WIRELESS_EXT < 18
@@ -7435,18 +7336,8 @@ static int ipw_send_qos_params_command(s
 		.len = (sizeof(struct ieee80211_qos_parameters) * 3)
 	};
 
-	if (!priv || !qos_param) {
-		IPW_ERROR("Invalid args\n");
-		return -1;
-	}
-
 	memcpy(cmd.param, qos_param, sizeof(*qos_param) * 3);
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send IPW_CMD_QOS_PARAMETERS command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 static int ipw_send_qos_info_command(struct ipw_priv *priv, struct ieee80211_qos_information_element
@@ -7457,18 +7348,8 @@ static int ipw_send_qos_info_command(str
 		.len = sizeof(*qos_param)
 	};
 
-	if (!priv || !qos_param) {
-		IPW_ERROR("Invalid args\n");
-		return -1;
-	}
-
 	memcpy(cmd.param, qos_param, sizeof(*qos_param));
-	if (ipw_send_cmd(priv, &cmd)) {
-		IPW_ERROR("failed to send CMD_QOS_INFO command\n");
-		return -1;
-	}
-
-	return 0;
+	return ipw_send_cmd(priv, &cmd);
 }
 
 #endif				/* CONFIG_IPW_QOS */
---
0.99.8.GIT


--- NEW FILE 2939-Added-cmdlog-in-non-debug-systems.txt ---
Subject: [PATCH] Added cmdlog in non-debug systems.
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124948349 -0500

You can now specify via the module parameter 'cmdlog' to allocate a
ring buffer for caching host commands sent to the firmware. They can
then be dumped at any time via the sysfs entry 'cmd_log'

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |  120 +++++++++++++++++++++++++++++++++++-----
 drivers/net/wireless/ipw2200.h |   11 ++++
 2 files changed, 117 insertions(+), 14 deletions(-)

applies-to: 48e2e961031aa7bb7fe7fef401ba132b1e53bf39
f6c5cb7c6f8a85045996bfc3442af963d6578d60
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index ef10077..bcb5993 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -44,6 +44,7 @@ MODULE_VERSION(DRV_VERSION);
 MODULE_AUTHOR(DRV_COPYRIGHT);
 MODULE_LICENSE("GPL");
 
+static int cmdlog = 0;
 static int debug = 0;
 static int channel = 0;
 static int mode = 0;
@@ -148,8 +149,8 @@ static int init_supported_rates(struct i
 static void ipw_set_hwcrypto_keys(struct ipw_priv *);
 static void ipw_send_wep_keys(struct ipw_priv *, int);
 
-static char *snprint_line(char *buf, size_t count,
-			  const u8 * data, u32 len, u32 ofs)
+static int snprint_line(char *buf, size_t count,
+			const u8 * data, u32 len, u32 ofs)
 {
 	int out, i, j, l;
 	char c;
@@ -180,7 +181,7 @@ static char *snprint_line(char *buf, siz
 			out += snprintf(buf + out, count - out, " ");
 	}
 
-	return buf;
+	return out;
 }
 
 static void printk_buf(int level, const u8 * data, u32 len)
@@ -191,14 +192,33 @@ static void printk_buf(int level, const 
 		return;
 
 	while (len) {
-		printk(KERN_DEBUG "%s\n",
-		       snprint_line(line, sizeof(line), &data[ofs],
-				    min(len, 16U), ofs));
+		snprint_line(line, sizeof(line), &data[ofs],
+			     min(len, 16U), ofs);
+		printk(KERN_DEBUG "%s\n", line);
 		ofs += 16;
 		len -= min(len, 16U);
 	}
 }
 
+static int snprintk_buf(u8 * output, size_t size, const u8 * data, size_t len)
+{
+	size_t out = size;
+	u32 ofs = 0;
+	int total = 0;
+
+	while (size && len) {
+		out = snprint_line(output, size, &data[ofs],
+				   min_t(size_t, len, 16U), ofs);
+
+		ofs += 16;
+		output += out;
+		size -= out;
+		len -= min_t(size_t, len, 16U);
+		total += out;
+	}
+	return total;
+}
+
 static u32 _ipw_read_reg32(struct ipw_priv *priv, u32 reg);
 #define ipw_read_reg32(a, b) _ipw_read_reg32(a, b)
 
@@ -272,9 +292,15 @@ static inline u32 __ipw_read32(char *f, 
 #define ipw_read32(ipw, ofs) __ipw_read32(__FILE__, __LINE__, ipw, ofs)
 
 static void _ipw_read_indirect(struct ipw_priv *, u32, u8 *, int);
-#define ipw_read_indirect(a, b, c, d) \
-	IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", __FILE__, __LINE__, (u32)(b), d); \
-	_ipw_read_indirect(a, b, c, d)
+static inline void __ipw_read_indirect(const char *f, int l,
+				       struct ipw_priv *a, u32 b, u8 * c, int d)
+{
+	IPW_DEBUG_IO("%s %d: read_indirect(0x%08X) %d bytes\n", f, l, (u32) (b),
+		     d);
+	_ipw_read_indirect(a, b, c, d);
+}
+
+#define ipw_read_indirect(a, b, c, d) __ipw_read_indirect(__FILE__, __LINE__, a, b, c, d)
 
 static void _ipw_write_indirect(struct ipw_priv *priv, u32 addr, u8 * data,
 				int num);
@@ -1070,6 +1096,7 @@ static struct ipw_fw_error *ipw_alloc_er
 			  "failed.\n");
 		return NULL;
 	}
+	error->jiffies = jiffies;
 	error->status = priv->status;
 	error->config = priv->config;
 	error->elem_len = elem_len;
@@ -1122,7 +1149,8 @@ static ssize_t show_error(struct device 
 	if (!priv->error)
 		return 0;
 	len += snprintf(buf + len, PAGE_SIZE - len,
-			"%08X%08X%08X",
+			"%08lX%08X%08X%08X",
+			priv->error->jiffies,
 			priv->error->status,
 			priv->error->config, priv->error->elem_len);
 	for (i = 0; i < priv->error->elem_len; i++)
@@ -1162,6 +1190,33 @@ static ssize_t clear_error(struct device
 
 static DEVICE_ATTR(error, S_IRUGO | S_IWUSR, show_error, clear_error);
 
+static ssize_t show_cmd_log(struct device *d,
+			    struct device_attribute *attr, char *buf)
+{
+	struct ipw_priv *priv = dev_get_drvdata(d);
+	u32 len = 0, i;
+	if (!priv->cmdlog)
+		return 0;
+	for (i = (priv->cmdlog_pos + 1) % priv->cmdlog_len;
+	     (i != priv->cmdlog_pos) && (PAGE_SIZE - len);
+	     i = (i + 1) % priv->cmdlog_len) {
+		len +=
+		    snprintf(buf + len, PAGE_SIZE - len,
+			     "\n%08lX%08X%08X%08X\n", priv->cmdlog[i].jiffies,
+			     priv->cmdlog[i].retcode, priv->cmdlog[i].cmd.cmd,
+			     priv->cmdlog[i].cmd.len);
+		len +=
+		    snprintk_buf(buf + len, PAGE_SIZE - len,
+				 (u8 *) priv->cmdlog[i].cmd.param,
+				 priv->cmdlog[i].cmd.len);
+		len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+	}
+	len += snprintf(buf + len, PAGE_SIZE - len, "\n");
+	return len;
+}
+
+static DEVICE_ATTR(cmd_log, S_IRUGO, show_cmd_log, NULL);
+
 static ssize_t show_scan_age(struct device *d, struct device_attribute *attr,
 			     char *buf)
 {
@@ -1825,6 +1880,15 @@ static int ipw_send_cmd(struct ipw_priv 
 
 	priv->status |= STATUS_HCMD_ACTIVE;
 
+	if (priv->cmdlog) {
+		priv->cmdlog[priv->cmdlog_pos].jiffies = jiffies;
+		priv->cmdlog[priv->cmdlog_pos].cmd.cmd = cmd->cmd;
+		priv->cmdlog[priv->cmdlog_pos].cmd.len = cmd->len;
+		memcpy(priv->cmdlog[priv->cmdlog_pos].cmd.param, cmd->param,
+		       cmd->len);
+		priv->cmdlog[priv->cmdlog_pos].retcode = -1;
+	}
+
 	IPW_DEBUG_HC("%s command (#%d) %d bytes: 0x%08X\n",
 		     get_cmd_string(cmd->cmd), cmd->cmd, cmd->len,
 		     priv->status);
@@ -1836,7 +1900,7 @@ static int ipw_send_cmd(struct ipw_priv 
 		IPW_ERROR("Failed to send %s: Reason %d\n",
 			  get_cmd_string(cmd->cmd), rc);
 		spin_unlock_irqrestore(&priv->lock, flags);
-		return rc;
+		goto exit;
 	}
 	spin_unlock_irqrestore(&priv->lock, flags);
 
@@ -1851,7 +1915,8 @@ static int ipw_send_cmd(struct ipw_priv 
 				  get_cmd_string(cmd->cmd));
 			priv->status &= ~STATUS_HCMD_ACTIVE;
 			spin_unlock_irqrestore(&priv->lock, flags);
-			return -EIO;
+			rc = -EIO;
+			goto exit;
 		}
 		spin_unlock_irqrestore(&priv->lock, flags);
 	}
@@ -1859,10 +1924,16 @@ static int ipw_send_cmd(struct ipw_priv 
 	if (priv->status & STATUS_RF_KILL_HW) {
 		IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
 			  get_cmd_string(cmd->cmd));
-		return -EIO;
+		rc = -EIO;
+		goto exit;
 	}
 
-	return 0;
+      exit:
+	if (priv->cmdlog) {
+		priv->cmdlog[priv->cmdlog_pos++].retcode = rc;
+		priv->cmdlog_pos %= priv->cmdlog_len;
+	}
+	return rc;
 }
 
 static int ipw_send_host_complete(struct ipw_priv *priv)
@@ -10712,6 +10783,18 @@ static int ipw_up(struct ipw_priv *priv)
 	if (priv->status & STATUS_EXIT_PENDING)
 		return -EIO;
 
+	if (cmdlog && !priv->cmdlog) {
+		priv->cmdlog = kmalloc(sizeof(*priv->cmdlog) * cmdlog,
+				       GFP_KERNEL);
+		if (priv->cmdlog == NULL) {
+			IPW_ERROR("Error allocating %d command log entries.\n",
+				  cmdlog);
+		} else {
+			memset(priv->cmdlog, 0, sizeof(*priv->cmdlog) * cmdlog);
+			priv->cmdlog_len = cmdlog;
+		}
+	}
+
 	for (i = 0; i < MAX_HW_RESTARTS; i++) {
 		/* Load the microcode, firmware, and eeprom.
 		 * Also start the clocks. */
@@ -10935,6 +11018,7 @@ static struct attribute *ipw_sysfs_entri
 	&dev_attr_cfg.attr,
 	&dev_attr_error.attr,
 	&dev_attr_event_log.attr,
+	&dev_attr_cmd_log.attr,
 	&dev_attr_eeprom_delay.attr,
 	&dev_attr_ucode_version.attr,
 	&dev_attr_rtc.attr,
@@ -11129,6 +11213,10 @@ static void ipw_pci_remove(struct pci_de
 	}
 	ipw_tx_queue_free(priv);
 
+	if (priv->cmdlog) {
+		kfree(priv->cmdlog);
+		priv->cmdlog = NULL;
+	}
 	/* ipw_down will ensure that there is no more pending work
 	 * in the workqueue's, so we can safely remove them now. */
 	cancel_delayed_work(&priv->adhoc_check);
@@ -11302,5 +11390,9 @@ MODULE_PARM_DESC(mode, "network mode (0=
 module_param(hwcrypto, int, 0444);
 MODULE_PARM_DESC(hwcrypto, "enable hardware crypto (default on)");
 
+module_param(cmdlog, int, 0444);
+MODULE_PARM_DESC(cmdlog,
+		 "allocate a ring buffer for logging firmware commands");
+
 module_exit(ipw_exit);
 module_init(ipw_init);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 9bf03ac..255f0cb 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1102,6 +1102,7 @@ struct ipw_event {
 } __attribute__ ((packed));
 
 struct ipw_fw_error {
+	unsigned long jiffies;
 	u32 status;
 	u32 config;
 	u32 elem_len;
@@ -1261,6 +1262,10 @@ struct ipw_priv {
 	struct work_struct led_act_off;
 	struct work_struct merge_networks;
 
+	struct ipw_cmd_log *cmdlog;
+	int cmdlog_len;
+	int cmdlog_pos;
+
 #define IPW_2200BG  1
 #define IPW_2915ABG 2
 	u8 adapter;
@@ -1853,6 +1858,12 @@ struct host_cmd {
 	u32 param[TFD_CMD_IMMEDIATE_PAYLOAD_LENGTH];
 } __attribute__ ((packed));
 
+struct ipw_cmd_log {
+	unsigned long jiffies;
+	int retcode;
+	struct host_cmd cmd;
+};
+
 #define CFG_BT_COEXISTENCE_MIN                  0x00
 #define CFG_BT_COEXISTENCE_DEFER                0x02
 #define CFG_BT_COEXISTENCE_KILL                 0x04
---
0.99.8.GIT


--- NEW FILE 2940-Migrated-some-of-the-channel-verification-code-back-into-the-driver-to.txt ---
Subject: [PATCH] Migrated some of the channel verification code back into the driver to
From: Liu Hong <hong.liu at intel.com>
Date: 1124461990 -0500
keep regulatory consistency in one location.

Signed-off-by: James Ketrenos

---

 drivers/net/wireless/ipw2200.c |  173 +++++++++++++++++++++++++++++++++++-----
 1 files changed, 152 insertions(+), 21 deletions(-)

applies-to: 47de65141268590002d7c9a091303681f84a6595
1fe0adb4314009362d28205bbf09f6d758e82002
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index bcb5993..40759e5 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -149,6 +149,12 @@ static int init_supported_rates(struct i
 static void ipw_set_hwcrypto_keys(struct ipw_priv *);
 static void ipw_send_wep_keys(struct ipw_priv *, int);
 
+static int ipw_is_valid_channel(struct ieee80211_device *, u8);
+static int ipw_channel_to_index(struct ieee80211_device *, u8);
+static u8 ipw_freq_to_channel(struct ieee80211_device *, u32);
+static int ipw_set_geo(struct ieee80211_device *, const struct ieee80211_geo *);
+static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *);
+
 static int snprint_line(char *buf, size_t count,
 			const u8 * data, u32 len, u32 ofs)
 {
@@ -1596,7 +1602,7 @@ static ssize_t store_speed_scan(struct d
 			break;
 		}
 
-		if (ieee80211_is_valid_channel(priv->ieee, channel))
+		if (ipw_is_valid_channel(priv->ieee, channel))
 			priv->speed_scan[pos++] = channel;
 		else
 			IPW_WARNING("Skipping invalid channel request: %d\n",
@@ -2194,7 +2200,7 @@ static int ipw_send_tx_power(struct ipw_
 
 static int ipw_set_tx_power(struct ipw_priv *priv)
 {
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
 	struct ipw_tx_power tx_power;
 	s8 max_power;
 	int i;
@@ -5503,6 +5509,15 @@ static int ipw_best_network(struct ipw_p
 		return 0;
 	}
 
+	/* Filter out invalid channel in current GEO */
+	if (!ipw_is_valid_channel(priv->ieee, network->channel)) {
+		IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
+				"because of invalid channel in current GEO\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid));
+		return 0;
+	}
+
 	/* Ensure that the rates supported by the driver are compatible with
 	 * this AP, including verification of basic rates (mandatory) */
 	if (!ipw_compatible_rates(priv, network, &rates)) {
@@ -5540,7 +5555,7 @@ static int ipw_best_network(struct ipw_p
 static void ipw_adhoc_create(struct ipw_priv *priv,
 			     struct ieee80211_network *network)
 {
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
 	int i;
 
 	/*
@@ -5555,10 +5570,10 @@ static void ipw_adhoc_create(struct ipw_
 	 * FW fatal error.
 	 *
 	 */
-	switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
+	switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
 	case IEEE80211_52GHZ_BAND:
 		network->mode = IEEE_A;
-		i = ieee80211_channel_to_index(priv->ieee, priv->channel);
+		i = ipw_channel_to_index(priv->ieee, priv->channel);
 		if (i == -1)
 			BUG();
 		if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
@@ -5572,6 +5587,13 @@ static void ipw_adhoc_create(struct ipw_
 			network->mode = IEEE_G;
 		else
 			network->mode = IEEE_B;
+		i = ipw_channel_to_index(priv->ieee, priv->channel);
+		if (i == -1)
+			BUG();
+		if (geo->bg[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
+			IPW_WARNING("Overriding invalid channel\n");
+			priv->channel = geo->bg[0].channel;
+		}
 		break;
 
 	default:
@@ -5899,7 +5921,7 @@ static void ipw_add_scan_channels(struct
 	const struct ieee80211_geo *geo;
 	int i;
 
-	geo = ieee80211_get_geo(priv->ieee);
+	geo = ipw_get_geo(priv->ieee);
 
 	if (priv->ieee->freq_band & IEEE80211_52GHZ_BAND) {
 		int start = channel_index;
@@ -5909,7 +5931,11 @@ static void ipw_add_scan_channels(struct
 				continue;
 			channel_index++;
 			scan->channels_list[channel_index] = geo->a[i].channel;
-			ipw_set_scan_type(scan, channel_index, scan_type);
+			ipw_set_scan_type(scan, channel_index,
+					  geo->a[i].
+					  flags & IEEE80211_CH_PASSIVE_ONLY ?
+					  IPW_SCAN_PASSIVE_FULL_DWELL_SCAN :
+					  scan_type);
 		}
 
 		if (start != channel_index) {
@@ -5922,6 +5948,7 @@ static void ipw_add_scan_channels(struct
 	if (priv->ieee->freq_band & IEEE80211_24GHZ_BAND) {
 		int start = channel_index;
 		if (priv->config & CFG_SPEED_SCAN) {
+			int index;
 			u8 channels[IEEE80211_24GHZ_CHANNELS] = {
 				/* nop out the list */
 				[0] = 0
@@ -5953,8 +5980,14 @@ static void ipw_add_scan_channels(struct
 				priv->speed_scan_pos++;
 				channel_index++;
 				scan->channels_list[channel_index] = channel;
+				index =
+				    ipw_channel_to_index(priv->ieee, channel);
 				ipw_set_scan_type(scan, channel_index,
-						  scan_type);
+						  geo->bg[index].
+						  flags &
+						  IEEE80211_CH_PASSIVE_ONLY ?
+						  IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
+						  : scan_type);
 			}
 		} else {
 			for (i = 0; i < geo->bg_channels; i++) {
@@ -5965,7 +5998,11 @@ static void ipw_add_scan_channels(struct
 				scan->channels_list[channel_index] =
 				    geo->bg[i].channel;
 				ipw_set_scan_type(scan, channel_index,
-						  scan_type);
+						  geo->bg[i].
+						  flags &
+						  IEEE80211_CH_PASSIVE_ONLY ?
+						  IPW_SCAN_PASSIVE_FULL_DWELL_SCAN
+						  : scan_type);
 			}
 		}
 
@@ -6017,7 +6054,7 @@ static int ipw_request_scan(struct ipw_p
 
 	scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
 	    cpu_to_le16(20);
-	scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(20);
+	scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
 
 	scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
 
@@ -6026,7 +6063,7 @@ static int ipw_request_scan(struct ipw_p
 		u8 channel;
 		u8 band = 0;
 
-		switch (ieee80211_is_valid_channel(priv->ieee, priv->channel)) {
+		switch (ipw_is_valid_channel(priv->ieee, priv->channel)) {
 		case IEEE80211_52GHZ_BAND:
 			band = (u8) (IPW_A_MODE << 6) | 1;
 			channel = priv->channel;
@@ -8401,10 +8438,11 @@ static int ipw_wx_set_freq(struct net_de
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
 	struct iw_freq *fwrq = &wrqu->freq;
 	int ret = 0, i;
-	u8 channel;
+	u8 channel, flags;
+	int band;
 
 	if (fwrq->m == 0) {
 		IPW_DEBUG_WX("SET Freq/Channel -> any\n");
@@ -8415,20 +8453,23 @@ static int ipw_wx_set_freq(struct net_de
 	}
 	/* if setting by freq convert to channel */
 	if (fwrq->e == 1) {
-		channel = ieee80211_freq_to_channel(priv->ieee, fwrq->m);
+		channel = ipw_freq_to_channel(priv->ieee, fwrq->m);
 		if (channel == 0)
 			return -EINVAL;
 	} else
 		channel = fwrq->m;
 
-	if (!ieee80211_is_valid_channel(priv->ieee, channel))
+	if (!(band = ipw_is_valid_channel(priv->ieee, channel)))
 		return -EINVAL;
 
-	if (priv->ieee->iw_mode == IW_MODE_ADHOC && priv->ieee->mode & IEEE_A) {
-		i = ieee80211_channel_to_index(priv->ieee, channel);
+	if (priv->ieee->iw_mode == IW_MODE_ADHOC) {
+		i = ipw_channel_to_index(priv->ieee, channel);
 		if (i == -1)
 			return -EINVAL;
-		if (geo->a[i].flags & IEEE80211_CH_PASSIVE_ONLY) {
+
+		flags = (band == IEEE80211_24GHZ_BAND) ?
+		    geo->bg[i].flags : geo->a[i].flags;
+		if (flags & IEEE80211_CH_PASSIVE_ONLY) {
 			IPW_DEBUG_WX("Invalid Ad-Hoc channel for 802.11a\n");
 			return -EINVAL;
 		}
@@ -8546,7 +8587,7 @@ static int ipw_wx_get_range(struct net_d
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct iw_range *range = (struct iw_range *)extra;
-	const struct ieee80211_geo *geo = ieee80211_get_geo(priv->ieee);
+	const struct ieee80211_geo *geo = ipw_get_geo(priv->ieee);
 	int i = 0, j;
 
 	wrqu->data.length = sizeof(*range);
@@ -9147,7 +9188,7 @@ static int ipw_request_direct_scan(struc
 
 	scan.dwell_time[IPW_SCAN_ACTIVE_BROADCAST_AND_DIRECT_SCAN] =
 	    cpu_to_le16(20);
-	scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(20);
+	scan.dwell_time[IPW_SCAN_PASSIVE_FULL_DWELL_SCAN] = cpu_to_le16(120);
 	scan.dwell_time[IPW_SCAN_ACTIVE_DIRECT_SCAN] = cpu_to_le16(20);
 
 	scan.full_scan_index = cpu_to_le32(ieee80211_get_scans(priv->ieee));
@@ -10775,6 +10816,96 @@ static const struct ieee80211_geo ipw_ge
 	 }
 };
 
+/* GEO code borrowed from ieee80211_geo.c */
+static int ipw_is_valid_channel(struct ieee80211_device *ieee, u8 channel)
+{
+	int i;
+
+	/* Driver needs to initialize the geography map before using
+	 * these helper functions */
+	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+		for (i = 0; i < ieee->geo.bg_channels; i++)
+			/* NOTE: If G mode is currently supported but
+			 * this is a B only channel, we don't see it
+			 * as valid. */
+			if ((ieee->geo.bg[i].channel == channel) &&
+			    (!(ieee->mode & IEEE_G) ||
+			     !(ieee->geo.bg[i].flags & IEEE80211_CH_B_ONLY)))
+				return IEEE80211_24GHZ_BAND;
+
+	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+		for (i = 0; i < ieee->geo.a_channels; i++)
+			if (ieee->geo.a[i].channel == channel)
+				return IEEE80211_52GHZ_BAND;
+
+	return 0;
+}
+
+static int ipw_channel_to_index(struct ieee80211_device *ieee, u8 channel)
+{
+	int i;
+
+	/* Driver needs to initialize the geography map before using
+	 * these helper functions */
+	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+		for (i = 0; i < ieee->geo.bg_channels; i++)
+			if (ieee->geo.bg[i].channel == channel)
+				return i;
+
+	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+		for (i = 0; i < ieee->geo.a_channels; i++)
+			if (ieee->geo.a[i].channel == channel)
+				return i;
+
+	return -1;
+}
+
+static u8 ipw_freq_to_channel(struct ieee80211_device *ieee, u32 freq)
+{
+	int i;
+
+	/* Driver needs to initialize the geography map before using
+	 * these helper functions */
+	BUG_ON(ieee->geo.bg_channels == 0 && ieee->geo.a_channels == 0);
+
+	freq /= 100000;
+
+	if (ieee->freq_band & IEEE80211_24GHZ_BAND)
+		for (i = 0; i < ieee->geo.bg_channels; i++)
+			if (ieee->geo.bg[i].freq == freq)
+				return ieee->geo.bg[i].channel;
+
+	if (ieee->freq_band & IEEE80211_52GHZ_BAND)
+		for (i = 0; i < ieee->geo.a_channels; i++)
+			if (ieee->geo.a[i].freq == freq)
+				return ieee->geo.a[i].channel;
+
+	return 0;
+}
+
+static int ipw_set_geo(struct ieee80211_device *ieee,
+		       const struct ieee80211_geo *geo)
+{
+	memcpy(ieee->geo.name, geo->name, 3);
+	ieee->geo.name[3] = '\0';
+	ieee->geo.bg_channels = geo->bg_channels;
+	ieee->geo.a_channels = geo->a_channels;
+	memcpy(ieee->geo.bg, geo->bg, geo->bg_channels *
+	       sizeof(struct ieee80211_channel));
+	memcpy(ieee->geo.a, geo->a, ieee->geo.a_channels *
+	       sizeof(struct ieee80211_channel));
+	return 0;
+}
+
+static const struct ieee80211_geo *ipw_get_geo(struct ieee80211_device *ieee)
+{
+	return &ieee->geo;
+}
+
 #define MAX_HW_RESTARTS 5
 static int ipw_up(struct ipw_priv *priv)
 {
@@ -10816,7 +10947,7 @@ static int ipw_up(struct ipw_priv *priv)
 		}
 		if (j == ARRAY_SIZE(ipw_geos))
 			j = 0;
-		if (ieee80211_set_geo(priv->ieee, &ipw_geos[j])) {
+		if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
 			IPW_WARNING("Could not set geography.");
 			return 0;
 		}
---
0.99.8.GIT


--- NEW FILE 2941-Updated-ipw2200-to-use-the-new-ieee80211-callbacks.txt ---
Subject: [PATCH] Updated ipw2200 to use the new ieee80211 callbacks
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124475535 -0500
(handle_probe_response, handle_beacon, handle_association_response).

Fixed a problem with ipw_send_cmd() returning non-zero on success.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   61 +++++++++++++++++++++++-----------------
 1 files changed, 35 insertions(+), 26 deletions(-)

applies-to: 63809744601a0f97ed8499c72377ab49d78a78ab
3b9990cb1751d3d267c0e5c94bff0f155c944c66
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 40759e5..53a6bb2 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1925,7 +1925,8 @@ static int ipw_send_cmd(struct ipw_priv 
 			goto exit;
 		}
 		spin_unlock_irqrestore(&priv->lock, flags);
-	}
+	} else
+		rc = 0;
 
 	if (priv->status & STATUS_RF_KILL_HW) {
 		IPW_ERROR("Failed to send %s: Aborted due to RF kill switch.\n",
@@ -7011,9 +7012,9 @@ u8 ipw_qos_current_mode(struct ipw_priv 
 /*
 * Handle management frame beacon and probe response
 */
-static int ipw_qos_handle_probe_reponse(struct ipw_priv *priv,
-					int active_network,
-					struct ieee80211_network *network)
+static int ipw_qos_handle_probe_response(struct ipw_priv *priv,
+					 int active_network,
+					 struct ieee80211_network *network)
 {
 	u32 size = sizeof(struct ieee80211_qos_parameters);
 
@@ -7407,35 +7408,41 @@ static void ipw_bg_qos_activate(void *da
 	up(&priv->sem);
 }
 
-/*
-* Handler for probe responce and beacon frame
-*/
-static int ipw_handle_management(struct net_device *dev,
-				 struct ieee80211_network *network, u16 type)
+static int ipw_handle_probe_response(struct net_device *dev,
+				     struct ieee80211_probe_response *resp,
+				     struct ieee80211_network *network)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-	int active_network;
+	int active_network = ((priv->status & STATUS_ASSOCIATED) &&
+			      (network == priv->assoc_network));
 
-	if (priv->status & STATUS_ASSOCIATED && network == priv->assoc_network)
-		active_network = 1;
-	else
-		active_network = 0;
+	ipw_qos_handle_probe_response(priv, active_network, network);
 
-	switch (type) {
-	case IEEE80211_STYPE_PROBE_RESP:
-	case IEEE80211_STYPE_BEACON:
-		ipw_qos_handle_probe_reponse(priv, active_network, network);
-		break;
-	case IEEE80211_STYPE_ASSOC_RESP:
-		ipw_qos_association_resp(priv, network);
-		break;
-	default:
-		break;
-	}
+	return 0;
+}
+
+static int ipw_handle_beacon(struct net_device *dev,
+			     struct ieee80211_beacon *resp,
+			     struct ieee80211_network *network)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	int active_network = ((priv->status & STATUS_ASSOCIATED) &&
+			      (network == priv->assoc_network));
+
+	ipw_qos_handle_probe_response(priv, active_network, network);
 
 	return 0;
 }
 
+static int ipw_handle_assoc_response(struct net_device *dev,
+				     struct ieee80211_assoc_response *resp,
+				     struct ieee80211_network *network)
+{
+	struct ipw_priv *priv = ieee80211_priv(dev);
+	ipw_qos_association_resp(priv, network);
+	return 0;
+}
+
 static int ipw_send_qos_params_command(struct ipw_priv *priv, struct ieee80211_qos_parameters
 				       *qos_param)
 {
@@ -11260,7 +11267,9 @@ static int ipw_pci_probe(struct pci_dev 
 	priv->ieee->is_queue_full = ipw_net_is_queue_full;
 
 #ifdef CONFIG_IPW_QOS
-	priv->ieee->handle_management = ipw_handle_management;
+	priv->ieee->handle_probe_response = ipw_handle_beacon;
+	priv->ieee->handle_beacon = ipw_handle_probe_response;
+	priv->ieee->handle_assoc_response = ipw_handle_assoc_response;
 #endif				/* CONFIG_IPW_QOS */
 
 	priv->ieee->perfect_rssi = -20;
---
0.99.8.GIT


--- NEW FILE 2942-Added-wait_state-wakeup-on-scan-completion.txt ---
Subject: [PATCH] Added wait_state wakeup on scan completion.
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124948983 -0500
Fixed copyright date in ipw2200.h

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |    1 +
 drivers/net/wireless/ipw2200.h |    2 +-
 2 files changed, 2 insertions(+), 1 deletions(-)

applies-to: 4889e130e3d3482a8784cdd7d0d38b8bcc93b246
a0e04ab36048eb1c3da2524b5b0b802b6ab064f0
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 53a6bb2..9ced5b7 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -4450,6 +4450,7 @@ static inline void ipw_rx_notification(s
 			priv->status &=
 			    ~(STATUS_SCANNING | STATUS_SCAN_ABORTING);
 
+			wake_up_interruptible(&priv->wait_state);
 			cancel_delayed_work(&priv->scan_check);
 
 			if (priv->status & STATUS_EXIT_PENDING)
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 255f0cb..f2056b6 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1,6 +1,6 @@
 /******************************************************************************
 
-  Copyright(c) 2003 - 2004 Intel Corporation. All rights reserved.
+  Copyright(c) 2003 - 2005 Intel Corporation. All rights reserved.
 
   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
---
0.99.8.GIT


--- NEW FILE 2943-Bug-455-Fix-frequent-channel-change-generates-firmware-fatal-error.txt ---
Subject: [PATCH] [Bug 455] Fix frequent channel change generates firmware fatal error.
From: Hong Liu <hong.liu at intel.com>
Date: 1124962573 +0800

Because of the frequent channel change, it is possible that when we are
try to associate with channel 1 (authenticated but not associated).
Another channel change comes at this time, then the driver will issue
disassociate command to the firmware which will cause the fatal error.

It seems that the association/disassociation procedure should not be
interrupted.

The patch attached adds test on STATUS_ASSOCIATING | STATUS_DISASSOCIATING
in ipw_send_cmd(), when ensures that commands will not be sent to firmware
when we are in these two status.

Signed-off-by: Hong Liu <hong.liu at intel.com>
Signed-off-by: Zhu Yi <yi.zhu at intel.com>

---

 drivers/net/wireless/ipw2200.c |   31 +++++++++++++++++++++++++------
 1 files changed, 25 insertions(+), 6 deletions(-)

applies-to: a12ae524c5da22d51a66440822776b565d22c31c
7b99659f97ca20e5f1ea56253a9449d278d825d5
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 9ced5b7..4cdb474 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1884,6 +1884,18 @@ static int ipw_send_cmd(struct ipw_priv 
 		return -EAGAIN;
 	}
 
+	if (priv->status & STATUS_ASSOCIATING) {
+		IPW_DEBUG_HC("abandon a command while associating\n");
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return -1;
+	}
+
+	if (priv->status & STATUS_DISASSOCIATING) {
+		IPW_DEBUG_HC("abandon a command while disassociating\n");
+		spin_unlock_irqrestore(&priv->lock, flags);
+		return -1;
+	}
+
 	priv->status |= STATUS_HCMD_ACTIVE;
 
 	if (priv->cmdlog) {
@@ -3671,7 +3683,13 @@ static void ipw_send_disassociate(struct
 {
 	int err;
 
-	if (!(priv->status & (STATUS_ASSOCIATING | STATUS_ASSOCIATED))) {
+	if (priv->status & STATUS_ASSOCIATING) {
+		IPW_DEBUG_ASSOC("Disassociating while associating.\n");
+		queue_work(priv->workqueue, &priv->disassociate);
+		return;
+	}
+
+	if (!(priv->status & STATUS_ASSOCIATED)) {
 		IPW_DEBUG_ASSOC("Disassociating while not associated.\n");
 		return;
 	}
@@ -3681,9 +3699,6 @@ static void ipw_send_disassociate(struct
 			MAC_ARG(priv->assoc_request.bssid),
 			priv->assoc_request.channel);
 
-	priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
-	priv->status |= STATUS_DISASSOCIATING;
-
 	if (quiet)
 		priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
 	else
@@ -3695,6 +3710,9 @@ static void ipw_send_disassociate(struct
 		return;
 	}
 
+	priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
+	priv->status |= STATUS_DISASSOCIATING;
+
 }
 
 static int ipw_disassociate(void *data)
@@ -7625,8 +7643,6 @@ static int ipw_associate_network(struct 
 	 */
 	priv->channel = network->channel;
 	memcpy(priv->bssid, network->bssid, ETH_ALEN);
-	priv->status |= STATUS_ASSOCIATING;
-	priv->status &= ~STATUS_SECURITY_UPDATED;
 
 	priv->assoc_network = network;
 
@@ -7640,6 +7656,9 @@ static int ipw_associate_network(struct 
 		return err;
 	}
 
+	priv->status |= STATUS_ASSOCIATING;
+	priv->status &= ~STATUS_SECURITY_UPDATED;
+
 	IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n",
 		  escape_essid(priv->essid, priv->essid_len),
 		  MAC_ARG(priv->bssid));
---
0.99.8.GIT


--- NEW FILE 2944-Bug-760-Fix-setting-WEP-key-in-monitor-mode-causes-IV-lost.txt ---
Subject: [PATCH] [Bug 760] Fix setting WEP key in monitor mode causes IV lost.
From: Zhu Yi <yi.zhu at intel.com>
Date: 1124962994 +0800

Signed-off-by: Zhu Yi <yi.zhu at intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 318b810e66466299874004b202fa7ee9a4538878
55135791819270a412dfb99f66301f02c72edadf
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 4cdb474..bda292f 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -7907,7 +7907,7 @@ static void ipw_handle_data_packet(struc
 	IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
 
 	/* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
-	if (!priv->ieee->host_decrypt)
+	if (!priv->ieee->host_decrypt && priv->ieee->iw_mode != IW_MODE_MONITOR)
 		ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
 	if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
---
0.99.8.GIT


--- NEW FILE 2945-Don-t-set-hardware-WEP-if-we-are-actually-using-TKIP-AES.txt ---
Subject: [PATCH] Don't set hardware WEP if we are actually using TKIP/AES.
From: Hong Liu <hong.liu at intel.com>
Date: 1124963149 +0800

Signed-off-by: Hong Liu <hong.liu at intel.com>

---

 drivers/net/wireless/ipw2100.c |    7 +++++--
 1 files changed, 5 insertions(+), 2 deletions(-)

applies-to: b854cf6f17428f9610cf9868e0a51b66b6465b1a
054b08d48464bfa8e5be69829b59bd599c5dcd72
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index eaf4707..83ba08c 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -5443,8 +5443,11 @@ static void shim__set_security(struct ne
 			else
 				memcpy(priv->ieee->sec.keys[i], sec->keys[i],
 				       sec->key_sizes[i]);
-			priv->ieee->sec.flags |= (1 << i);
-			priv->status |= STATUS_SECURITY_UPDATED;
+			if (sec->level == SEC_LEVEL_1) {
+				priv->ieee->sec.flags |= (1 << i);
+				priv->status |= STATUS_SECURITY_UPDATED;
+			} else
+				priv->ieee->sec.flags &= ~(1 << i);
 		}
 	}
 
---
0.99.8.GIT


--- NEW FILE 2946-Make-all-the-places-the-firmware-fails-to-load-showerrors-in-decimal.txt ---
Subject: [PATCH] Make all the places the firmware fails to load showerrors (in decimal,
From: Peter Jones <pjones at redhat.com>
Date: 1125034414 -0500
so you can cross-reference errno.h easily).

Signed-off-by: Peter Jones <pjones at redhat.com>
Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |    8 ++++----
 1 files changed, 4 insertions(+), 4 deletions(-)

applies-to: c60cb9e8e0407d8b98572e933c5fd250a82e05ee
a4f6bbb305123c2c42322a10a770be64089a17ca
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index bda292f..79697e8 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -3304,7 +3304,7 @@ static int ipw_load(struct ipw_priv *pri
 	rc = ipw_load_firmware(priv, bootfw->data + sizeof(struct fw_header),
 			       bootfw->size - sizeof(struct fw_header));
 	if (rc < 0) {
-		IPW_ERROR("Unable to load boot firmware\n");
+		IPW_ERROR("Unable to load boot firmware: %d\n", rc);
 		goto error;
 	}
 
@@ -3327,7 +3327,7 @@ static int ipw_load(struct ipw_priv *pri
 	rc = ipw_load_ucode(priv, ucode->data + sizeof(struct fw_header),
 			    ucode->size - sizeof(struct fw_header));
 	if (rc < 0) {
-		IPW_ERROR("Unable to load ucode\n");
+		IPW_ERROR("Unable to load ucode: %d\n", rc);
 		goto error;
 	}
 
@@ -3339,7 +3339,7 @@ static int ipw_load(struct ipw_priv *pri
 			       sizeof(struct fw_header),
 			       firmware->size - sizeof(struct fw_header));
 	if (rc < 0) {
-		IPW_ERROR("Unable to load firmware\n");
+		IPW_ERROR("Unable to load firmware: %d\n", rc);
 		goto error;
 	}
 
@@ -10958,7 +10958,7 @@ static int ipw_up(struct ipw_priv *priv)
 		 * Also start the clocks. */
 		rc = ipw_load(priv);
 		if (rc) {
-			IPW_ERROR("Unable to load firmware: 0x%08X\n", rc);
+			IPW_ERROR("Unable to load firmware: %d\n", rc);
 			return rc;
 		}
 
---
0.99.8.GIT


--- NEW FILE 2947-Adds-radiotap-support-to-ipw2200-in-monitor-mode.txt ---
Subject: [PATCH] Adds radiotap support to ipw2200 in monitor mode..
From: Mike Kershaw <dragorn at kismetwireless.net>
Date: 1125034914 -0500

Signed-off-by: Mike Kershaw <dragorn at kismetwireless.net>
Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |  185 ++++++++++++++++++++++++++++++++++++++++
 drivers/net/wireless/ipw2200.h |    1 
 2 files changed, 186 insertions(+), 0 deletions(-)

applies-to: 6f43bf7bb84b7ef2459e2b1023fb1db34ffb8cbc
24a47dbd89a2738bc149de4685ae5a2a97193ae1
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 79697e8..86a4c23 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -7918,6 +7918,173 @@ static void ipw_handle_data_packet(struc
 	}
 }
 
+#ifdef CONFIG_IEEE80211_RADIOTAP
+static void ipw_handle_data_packet_monitor(struct ipw_priv *priv,
+					   struct ipw_rx_mem_buffer *rxb,
+					   struct ieee80211_rx_stats *stats)
+{
+	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
+	struct ipw_rx_frame *frame = &pkt->u.frame;
+
+	/* initial pull of some data */
+	u16 received_channel = frame->received_channel;
+	u8 antennaAndPhy = frame->antennaAndPhy;
+	s8 antsignal = frame->rssi_dbm - IPW_RSSI_TO_DBM;	/* call it signed anyhow */
+	u16 pktrate = frame->rate;
+
+	/* Magic struct that slots into the radiotap header -- no reason
+	 * to build this manually element by element, we can write it much
+	 * more efficiently than we can parse it. ORDER MATTERS HERE */
+	struct ipw_rt_hdr {
+		struct ieee80211_radiotap_header rt_hdr;
+		u8 rt_flags;	/* radiotap packet flags */
+		u8 rt_rate;	/* rate in 500kb/s */
+		u16 rt_channel;	/* channel in mhz */
+		u16 rt_chbitmask;	/* channel bitfield */
+		s8 rt_dbmsignal;	/* signal in dbM, kluged to signed */
+		u8 rt_antenna;	/* antenna number */
+	} *ipw_rt;
+
+	short len = le16_to_cpu(pkt->u.frame.length);
+
+	/* We received data from the HW, so stop the watchdog */
+	priv->net_dev->trans_start = jiffies;
+
+	/* We only process data packets if the
+	 * interface is open */
+	if (unlikely((le16_to_cpu(pkt->u.frame.length) + IPW_RX_FRAME_SIZE) >
+		     skb_tailroom(rxb->skb))) {
+		priv->ieee->stats.rx_errors++;
+		priv->wstats.discard.misc++;
+		IPW_DEBUG_DROP("Corruption detected! Oh no!\n");
+		return;
+	} else if (unlikely(!netif_running(priv->net_dev))) {
+		priv->ieee->stats.rx_dropped++;
+		priv->wstats.discard.misc++;
+		IPW_DEBUG_DROP("Dropping packet while interface is not up.\n");
+		return;
+	}
+
+	/* Libpcap 0.9.3+ can handle variable length radiotap, so we'll use
+	 * that now */
+	if (len > IPW_RX_BUF_SIZE - sizeof(struct ipw_rt_hdr)) {
+		/* FIXME: Should alloc bigger skb instead */
+		priv->ieee->stats.rx_dropped++;
+		priv->wstats.discard.misc++;
+		IPW_DEBUG_DROP("Dropping too large packet in monitor\n");
+		return;
+	}
+
+	/* copy the frame itself */
+	memmove(rxb->skb->data + sizeof(struct ipw_rt_hdr),
+		rxb->skb->data + IPW_RX_FRAME_SIZE, len);
+
+	/* Zero the radiotap static buffer  ...  We only need to zero the bytes NOT
+	 * part of our real header, saves a little time.
+	 *
+	 * No longer necessary since we fill in all our data.  Purge before merging
+	 * patch officially.
+	 * memset(rxb->skb->data + sizeof(struct ipw_rt_hdr), 0,
+	 *        IEEE80211_RADIOTAP_HDRLEN - sizeof(struct ipw_rt_hdr));
+	 */
+
+	ipw_rt = (struct ipw_rt_hdr *)rxb->skb->data;
+
+	ipw_rt->rt_hdr.it_version = PKTHDR_RADIOTAP_VERSION;
+	ipw_rt->rt_hdr.it_pad = 0;	/* always good to zero */
+	ipw_rt->rt_hdr.it_len = sizeof(struct ipw_rt_hdr);	/* total header+data */
+
+	/* Big bitfield of all the fields we provide in radiotap */
+	ipw_rt->rt_hdr.it_present =
+	    ((1 << IEEE80211_RADIOTAP_FLAGS) |
+	     (1 << IEEE80211_RADIOTAP_RATE) |
+	     (1 << IEEE80211_RADIOTAP_CHANNEL) |
+	     (1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) |
+	     (1 << IEEE80211_RADIOTAP_ANTENNA));
+
+	/* Zero the flags, we'll add to them as we go */
+	ipw_rt->rt_flags = 0;
+
+	/* Convert signal to DBM */
+	ipw_rt->rt_dbmsignal = antsignal;
+
+	/* Convert the channel data and set the flags */
+	ipw_rt->rt_channel = cpu_to_le16(ieee80211chan2mhz(received_channel));
+	if (received_channel > 14) {	/* 802.11a */
+		ipw_rt->rt_chbitmask =
+		    cpu_to_le16((IEEE80211_CHAN_OFDM | IEEE80211_CHAN_5GHZ));
+	} else if (antennaAndPhy & 32) {	/* 802.11b */
+		ipw_rt->rt_chbitmask =
+		    cpu_to_le16((IEEE80211_CHAN_CCK | IEEE80211_CHAN_2GHZ));
+	} else {		/* 802.11g */
+		ipw_rt->rt_chbitmask =
+		    (IEEE80211_CHAN_OFDM | IEEE80211_CHAN_2GHZ);
+	}
+
+	/* set the rate in multiples of 500k/s */
+	switch (pktrate) {
+	case IPW_TX_RATE_1MB:
+		ipw_rt->rt_rate = 2;
+		break;
+	case IPW_TX_RATE_2MB:
+		ipw_rt->rt_rate = 4;
+		break;
+	case IPW_TX_RATE_5MB:
+		ipw_rt->rt_rate = 10;
+		break;
+	case IPW_TX_RATE_6MB:
+		ipw_rt->rt_rate = 12;
+		break;
+	case IPW_TX_RATE_9MB:
+		ipw_rt->rt_rate = 18;
+		break;
+	case IPW_TX_RATE_11MB:
+		ipw_rt->rt_rate = 22;
+		break;
+	case IPW_TX_RATE_12MB:
+		ipw_rt->rt_rate = 24;
+		break;
+	case IPW_TX_RATE_18MB:
+		ipw_rt->rt_rate = 36;
+		break;
+	case IPW_TX_RATE_24MB:
+		ipw_rt->rt_rate = 48;
+		break;
+	case IPW_TX_RATE_36MB:
+		ipw_rt->rt_rate = 72;
+		break;
+	case IPW_TX_RATE_48MB:
+		ipw_rt->rt_rate = 96;
+		break;
+	case IPW_TX_RATE_54MB:
+		ipw_rt->rt_rate = 108;
+		break;
+	default:
+		ipw_rt->rt_rate = 0;
+		break;
+	}
+
+	/* antenna number */
+	ipw_rt->rt_antenna = (antennaAndPhy & 3);	/* Is this right? */
+
+	/* set the preamble flag if we have it */
+	if ((antennaAndPhy & 64))
+		ipw_rt->rt_flags |= IEEE80211_RADIOTAP_F_SHORTPRE;
+
+	/* Set the size of the skb to the size of the frame */
+	skb_put(rxb->skb, len + sizeof(struct ipw_rt_hdr));
+
+	IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
+
+	if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
+		priv->ieee->stats.rx_errors++;
+	else {			/* ieee80211_rx succeeded, so it now owns the SKB */
+		rxb->skb = NULL;
+		/* no LED during capture */
+	}
+}
+#endif
+
 static inline int is_network_packet(struct ipw_priv *priv,
 				    struct ieee80211_hdr_4addr *header)
 {
@@ -8147,8 +8314,14 @@ static void ipw_rx(struct ipw_priv *priv
 
 #ifdef CONFIG_IPW2200_MONITOR
 				if (priv->ieee->iw_mode == IW_MODE_MONITOR) {
+#ifdef CONFIG_IEEE80211_RADIOTAP
+					ipw_handle_data_packet_monitor(priv,
+								       rxb,
+								       &stats);
+#else
 					ipw_handle_data_packet(priv, rxb,
 							       &stats);
+#endif
 					break;
 				}
 #endif
@@ -8315,7 +8488,11 @@ static int ipw_sw_reset(struct ipw_priv 
 #ifdef CONFIG_IPW2200_MONITOR
 	case 2:
 		priv->ieee->iw_mode = IW_MODE_MONITOR;
+#ifdef CONFIG_IEEE80211_RADIOTAP
+		priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+#else
 		priv->net_dev->type = ARPHRD_IEEE80211;
+#endif
 		break;
 #endif
 	default:
@@ -8565,7 +8742,11 @@ static int ipw_wx_set_mode(struct net_de
 		priv->net_dev->type = ARPHRD_ETHER;
 
 	if (wrqu->mode == IW_MODE_MONITOR)
+#ifdef CONFIG_IEEE80211_RADIOTAP
+		priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+#else
 		priv->net_dev->type = ARPHRD_IEEE80211;
+#endif
 #endif				/* CONFIG_IPW2200_MONITOR */
 
 	/* Free the existing firmware and reset the fw_loaded
@@ -9598,7 +9779,11 @@ static int ipw_wx_set_monitor(struct net
 	IPW_DEBUG_WX("SET MONITOR: %d %d\n", enable, parms[1]);
 	if (enable) {
 		if (priv->ieee->iw_mode != IW_MODE_MONITOR) {
+#ifdef CONFIG_IEEE80211_RADIOTAP
+			priv->net_dev->type = ARPHRD_IEEE80211_RADIOTAP;
+#else
 			priv->net_dev->type = ARPHRD_IEEE80211;
+#endif
 			queue_work(priv->workqueue, &priv->adapter_restart);
 		}
 
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index f2056b6..28f1216 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -50,6 +50,7 @@
 #include <asm/io.h>
 
 #include <net/ieee80211.h>
+#include <net/ieee80211_radiotap.h>
 
 #define DRV_NAME	"ipw2200"
 
---
0.99.8.GIT


--- NEW FILE 2948-Fixed-is_network_packet-to-include-checking-for-broadcast-packets.txt ---
Subject: [PATCH] Fixed is_network_packet() to include checking for broadcast packets.
From: Peter Jones <pjones at redhat.com>
Date: 1125093066 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   12 +++++++-----
 1 files changed, 7 insertions(+), 5 deletions(-)

applies-to: 8f51a610a39581d48b6b9a6e7a0e4ba8420df8a3
90700fd982022f0519e7bd7595adb8084f36d1c6
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 86a4c23..d417ed7 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -8096,21 +8096,23 @@ static inline int is_network_packet(stru
 		if (!memcmp(header->addr2, priv->net_dev->dev_addr, ETH_ALEN))
 			return 0;
 
-		/* multicast packets to our IBSS go through */
-		if (is_multicast_ether_addr(header->addr1))
+		/* {broad,multi}cast packets to our BSSID go through */
+		if (is_multicast_ether_addr(header->addr1) ||
+		    is_broadcast_ether_addr(header->addr1))
 			return !memcmp(header->addr3, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
 		return !memcmp(header->addr1, priv->net_dev->dev_addr,
 			       ETH_ALEN);
 
-	case IW_MODE_INFRA:	/* Header: Dest. | AP{BSSID} | Source */
+	case IW_MODE_INFRA:	/* Header: Dest. | BSSID | Source */
 		/* packets from our adapter are dropped (echo) */
 		if (!memcmp(header->addr3, priv->net_dev->dev_addr, ETH_ALEN))
 			return 0;
 
-		/* {broad,multi}cast packets to our IBSS go through */
-		if (is_multicast_ether_addr(header->addr1))
+		/* {broad,multi}cast packets to our BSS go through */
+		if (is_multicast_ether_addr(header->addr1) ||
+		    is_broadcast_ether_addr(header->addr1))
 			return !memcmp(header->addr2, priv->bssid, ETH_ALEN);
 
 		/* packets to our adapter go through */
---
0.99.8.GIT


--- NEW FILE 2949-Mixed-PTK-GTK-CCMP-TKIP-support.txt ---
Subject: [PATCH] Mixed PTK/GTK CCMP/TKIP support.
From: Hong Liu <hong.liu at intel.com>
Date: 1125482842 +0800

Signed-off-by: Hong Liu <hong.liu at intel.com>

---

 drivers/net/wireless/ipw2200.c |   50 ++++++++++++++++++++++++++++++----------
 1 files changed, 37 insertions(+), 13 deletions(-)

applies-to: 297461b8ec67e914f0518be5ddb21831bb179b45
567deaf6d4a3372cd16b8719741ca3a6157c9615
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index d417ed7..c9b306a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -5771,7 +5771,8 @@ static void ipw_set_hwcrypto_keys(struct
 					    DCT_FLAG_EXT_SECURITY_CCM,
 					    priv->ieee->sec.active_key);
 
-		ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
+		if (!priv->ieee->host_mc_decrypt)
+			ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_CCM);
 		break;
 	case SEC_LEVEL_2:
 		if (priv->ieee->sec.flags & SEC_ACTIVE_KEY)
@@ -5786,9 +5787,6 @@ static void ipw_set_hwcrypto_keys(struct
 	default:
 		break;
 	}
-
-	ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
-	ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
 }
 
 static void ipw_adhoc_check(void *data)
@@ -6473,6 +6471,7 @@ static int ipw_wpa_set_encryption(struct
 				  struct ipw_param *param, int param_len)
 {
 	int ret = 0;
+	int group_key = 0;
 	struct ipw_priv *priv = ieee80211_priv(dev);
 	struct ieee80211_device *ieee = priv->ieee;
 	struct ieee80211_crypto_ops *ops;
@@ -6502,6 +6501,9 @@ static int ipw_wpa_set_encryption(struct
 		return -EINVAL;
 	}
 
+	if (param->u.crypt.idx != 0)
+		group_key = 1;
+
 	sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
 	if (strcmp(param->u.crypt.alg, "none") == 0) {
 		if (crypt) {
@@ -6517,11 +6519,19 @@ static int ipw_wpa_set_encryption(struct
 	sec.encrypt = 1;
 
 	/* IPW HW cannot build TKIP MIC, host decryption still needed. */
-	if (strcmp(param->u.crypt.alg, "TKIP") == 0)
-		ieee->host_encrypt_msdu = 1;
+	if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
+		if (group_key)
+			ieee->host_mc_decrypt = 1;
+		else
+			ieee->host_encrypt_msdu = 1;
+	}
 
-	if (!(ieee->host_encrypt || ieee->host_encrypt_msdu ||
-	      ieee->host_decrypt))
+	/*if (!(ieee->host_encrypt || ieee->host_encrypt_msdu ||
+	   ieee->host_decrypt))
+	   goto skip_host_crypt; */
+	if (group_key ? !ieee->host_mc_decrypt :
+	    !(ieee->host_encrypt || ieee->host_decrypt ||
+	      ieee->host_encrypt_msdu))
 		goto skip_host_crypt;
 
 	ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
@@ -6604,6 +6614,9 @@ static int ipw_wpa_set_encryption(struct
 			sec.flags |= SEC_LEVEL;
 			sec.level = SEC_LEVEL_3;
 		}
+		/* Don't set sec level for group keys. */
+		if (group_key)
+			sec.flags &= ~SEC_LEVEL;
 	}
       done:
 	if (ieee->set_security)
@@ -6953,15 +6966,21 @@ static int ipw_wx_set_encodeext(struct n
 	struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
 
 	if (hwcrypto) {
-		/* IPW HW can't build TKIP MIC, host decryption still needed */
 		if (ext->alg == IW_ENCODE_ALG_TKIP) {
-			priv->ieee->host_encrypt = 0;
-			priv->ieee->host_encrypt_msdu = 1;
-			priv->ieee->host_decrypt = 1;
+			/* IPW HW can't build TKIP MIC,
+			   host decryption still needed */
+			if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY)
+				priv->ieee->host_mc_decrypt = 1;
+			else {
+				priv->ieee->host_encrypt = 0;
+				priv->ieee->host_encrypt_msdu = 1;
+				priv->ieee->host_decrypt = 1;
+			}
 		} else {
 			priv->ieee->host_encrypt = 0;
 			priv->ieee->host_encrypt_msdu = 0;
 			priv->ieee->host_decrypt = 0;
+			priv->ieee->host_mc_decrypt = 0;
 		}
 	}
 
@@ -7878,6 +7897,7 @@ static void ipw_handle_data_packet(struc
 				   struct ipw_rx_mem_buffer *rxb,
 				   struct ieee80211_rx_stats *stats)
 {
+	struct ieee80211_hdr_4addr *hdr;
 	struct ipw_rx_packet *pkt = (struct ipw_rx_packet *)rxb->skb->data;
 
 	/* We received data from the HW, so stop the watchdog */
@@ -7907,7 +7927,10 @@ static void ipw_handle_data_packet(struc
 	IPW_DEBUG_RX("Rx packet of %d bytes.\n", rxb->skb->len);
 
 	/* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
-	if (!priv->ieee->host_decrypt && priv->ieee->iw_mode != IW_MODE_MONITOR)
+	hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
+	if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
+	    (is_multicast_ether_addr(hdr->addr1) ?
+	     !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
 		ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
 	if (!ieee80211_rx(priv->ieee, rxb->skb, stats))
@@ -8508,6 +8531,7 @@ static int ipw_sw_reset(struct ipw_priv 
 		priv->ieee->host_encrypt = 0;
 		priv->ieee->host_encrypt_msdu = 0;
 		priv->ieee->host_decrypt = 0;
+		priv->ieee->host_mc_decrypt = 0;
 	}
 	IPW_DEBUG_INFO("Hardware crypto [%s]\n", hwcrypto ? "on" : "off");
 
---
0.99.8.GIT


--- NEW FILE 2950-Card-with-WEP-enabled-and-using-shared-key-auth-will-have-firmware.txt ---
Subject: [PATCH] Card with WEP enabled and using shared-key auth will have firmware
From: Hong Liu <hong.liu at intel.com>
Date: 1125483267 +0800
error when it tries to auth to a WPA ap. The patch filters out WPA
networks if the card is not wpa enabled when selecting network to
associate to.

Signed-off-by: Hong Liu <hong.liu at intel.com>

---

 drivers/net/wireless/ipw2200.c |   10 ++++++++++
 1 files changed, 10 insertions(+), 0 deletions(-)

applies-to: 70b81b5a07473eb1a1de798e9271a1389306b43c
cdd1fa1e10a2231b5e24bde82550ac499aa5dcc4
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index c9b306a..e36a1fd 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -5510,6 +5510,15 @@ static int ipw_best_network(struct ipw_p
 		return 0;
 	}
 
+	if (!priv->ieee->wpa_enabled && (network->wpa_ie_len > 0 ||
+					 network->rsn_ie_len > 0)) {
+		IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
+				"because of WPA capability mismatch.\n",
+				escape_essid(network->ssid, network->ssid_len),
+				MAC_ARG(network->bssid));
+		return 0;
+	}
+
 	if ((priv->config & CFG_STATIC_BSSID) &&
 	    memcmp(network->bssid, priv->bssid, ETH_ALEN)) {
 		IPW_DEBUG_ASSOC("Network '%s (" MAC_FMT ")' excluded "
@@ -6228,6 +6237,7 @@ static int ipw_wpa_enable(struct ipw_pri
 {
 	/* This is called when wpa_supplicant loads and closes the driver
 	 * interface. */
+	priv->ieee->wpa_enabled = value;
 	return 0;
 }
 
---
0.99.8.GIT


--- NEW FILE 2951-Fixed-problem-with-get_cmd_string-not-existing-if-CONFIG_IPW_DEBUG-disabled.txt ---
Subject: [PATCH] Fixed problem with get_cmd_string not existing if CONFIG_IPW_DEBUG disabled.
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1126135148 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 --
 1 files changed, 0 insertions(+), 2 deletions(-)

applies-to: 8c2a2ff794bf3e53b350f0ee7e8971f7d96aae32
fb7ccc9e6d1a2872ea8a07154f1689d19a7576c5
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index e36a1fd..43dab7a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1809,7 +1809,6 @@ static void ipw_irq_tasklet(struct ipw_p
 	spin_unlock_irqrestore(&priv->lock, flags);
 }
 
-#ifdef CONFIG_IPW_DEBUG
 #define IPW_CMD(x) case IPW_CMD_ ## x : return #x
 static char *get_cmd_string(u8 cmd)
 {
@@ -1868,7 +1867,6 @@ static char *get_cmd_string(u8 cmd)
 		return "UNKNOWN";
 	}
 }
-#endif
 
 #define HOST_COMPLETE_TIMEOUT HZ
 static int ipw_send_cmd(struct ipw_priv *priv, struct host_cmd *cmd)
---
0.99.8.GIT


--- NEW FILE 2952-Removed-PF_SYNCTHREAD-legacy.txt ---
Subject: [PATCH] Removed PF_SYNCTHREAD legacy.
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1126136343 -0500

The PF_SYNCTHREAD check was introduced to try and remain compatible with
SWSUSP2.  This check is no longer needed with newer versions.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2100.c |    5 +----
 1 files changed, 1 insertions(+), 4 deletions(-)

applies-to: 9639c1c101af0d99f3f87f5a49d9ad9add887b7d
392d0f6d0752e6a3e25c3e3da95d78c53b0fd7a1
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 83ba08c..23a74ac 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -6433,11 +6433,8 @@ static struct net_device *ipw2100_alloc_
 	INIT_LIST_HEAD(&priv->fw_pend_list);
 	INIT_STAT(&priv->fw_pend_stat);
 
-#ifdef PF_SYNCTHREAD
-	priv->workqueue = create_workqueue(DRV_NAME, 0);
-#else
 	priv->workqueue = create_workqueue(DRV_NAME);
-#endif
+
 	INIT_WORK(&priv->reset_work,
 		  (void (*)(void *))ipw2100_reset_adapter, priv);
 	INIT_WORK(&priv->security_work,
---
0.99.8.GIT


--- NEW FILE 2953-Fixes-problem-with-WEP-not-working-association-succeeds-but-no-Tx-Rx.txt ---
Subject: [PATCH] Fixes problem with WEP not working (association succeeds, but no Tx/Rx)
From: Hong Liu <hong.liu at intel.com>
Date: 1126539813 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 ++
 1 files changed, 2 insertions(+), 0 deletions(-)

applies-to: 7af3f936974a169cc86a20f463f83af0f308276c
29cb843e6457c45c4a257a0d2080da3fd7fb9d1e
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 43dab7a..217b657 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -5789,6 +5789,8 @@ static void ipw_set_hwcrypto_keys(struct
 		break;
 	case SEC_LEVEL_1:
 		ipw_send_wep_keys(priv, DCW_WEP_KEY_SEC_TYPE_WEP);
+		ipw_set_hw_decrypt_unicast(priv, priv->ieee->sec.level);
+		ipw_set_hw_decrypt_multicast(priv, priv->ieee->sec.level);
 		break;
 	case SEC_LEVEL_0:
 	default:
---
0.99.8.GIT


--- NEW FILE 2954-Fix-bug-771-Too-many-8-bytes-recieved-when-using-AES-hwcrypto.txt ---
Subject: [PATCH] [Fix bug# 771] Too many (8) bytes recieved when using AES/hwcrypto
From: Zhu Yi <yi.zhu at intel.com>
Date: 1126540128 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   10 ++--------
 1 files changed, 2 insertions(+), 8 deletions(-)

applies-to: 8342a3735fac973f66a469d31630b3bb3cd4a7cf
f4ff497d45c7071166277a39590cc59b50dc893c
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 217b657..549f582 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -7877,10 +7877,7 @@ static void ipw_rebuild_decrypted_skb(st
 		memmove(skb->data + IEEE80211_3ADDR_LEN,
 			skb->data + IEEE80211_3ADDR_LEN + 8,
 			skb->len - IEEE80211_3ADDR_LEN - 8);
-		if (fc & IEEE80211_FCTL_MOREFRAGS)
-			skb_trim(skb, skb->len - 16);	/* 2*MIC */
-		else
-			skb_trim(skb, skb->len - 8);	/* MIC */
+		skb_trim(skb, skb->len - 16);	/* CCMP_HDR_LEN + CCMP_MIC_LEN */
 		break;
 	case SEC_LEVEL_2:
 		break;
@@ -7889,10 +7886,7 @@ static void ipw_rebuild_decrypted_skb(st
 		memmove(skb->data + IEEE80211_3ADDR_LEN,
 			skb->data + IEEE80211_3ADDR_LEN + 4,
 			skb->len - IEEE80211_3ADDR_LEN - 4);
-		if (fc & IEEE80211_FCTL_MOREFRAGS)
-			skb_trim(skb, skb->len - 8);	/* 2*ICV */
-		else
-			skb_trim(skb, skb->len - 4);	/* ICV */
+		skb_trim(skb, skb->len - 8);	/* IV + ICV */
 		break;
 	case SEC_LEVEL_0:
 		break;
---
0.99.8.GIT


--- NEW FILE 2955-Fixes-WEP-firmware-error-condition.txt ---
Subject: [PATCH] Fixes WEP firmware error condition.
From: Hong Liu <hong.liu at intel.com>
Date: 1126749855 -0500

The problem is caused by the patch in bug455 -- Channel change flood
generates fatal error.

The patch set the DISASSOCIATING status bit after sending the command.
The process was scheduled out when waiting for the command to be sent to
the card. The disassociated notification clears the DISASSOCIATING bit
in the tasklet before the process set the bit.

Move the bit setting code before sending the command now.

Signed-off-by: Hong Liu <hong.liu at intel.com>
Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   31 +++++++++++++------------------
 1 files changed, 13 insertions(+), 18 deletions(-)

applies-to: 1db4370e38cc2ba866dc6068fadee23f8f587590
e63247269de722c3e753991025fb7f15c6aba9aa
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 549f582..a763092 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -1882,18 +1882,6 @@ static int ipw_send_cmd(struct ipw_priv 
 		return -EAGAIN;
 	}
 
-	if (priv->status & STATUS_ASSOCIATING) {
-		IPW_DEBUG_HC("abandon a command while associating\n");
-		spin_unlock_irqrestore(&priv->lock, flags);
-		return -1;
-	}
-
-	if (priv->status & STATUS_DISASSOCIATING) {
-		IPW_DEBUG_HC("abandon a command while disassociating\n");
-		spin_unlock_irqrestore(&priv->lock, flags);
-		return -1;
-	}
-
 	priv->status |= STATUS_HCMD_ACTIVE;
 
 	if (priv->cmdlog) {
@@ -3697,10 +3685,14 @@ static void ipw_send_disassociate(struct
 			MAC_ARG(priv->assoc_request.bssid),
 			priv->assoc_request.channel);
 
+	priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
+	priv->status |= STATUS_DISASSOCIATING;
+
 	if (quiet)
 		priv->assoc_request.assoc_type = HC_DISASSOC_QUIET;
 	else
 		priv->assoc_request.assoc_type = HC_DISASSOCIATE;
+
 	err = ipw_send_associate(priv, &priv->assoc_request);
 	if (err) {
 		IPW_DEBUG_HC("Attempt to send [dis]associate command "
@@ -3708,9 +3700,6 @@ static void ipw_send_disassociate(struct
 		return;
 	}
 
-	priv->status &= ~(STATUS_ASSOCIATING | STATUS_ASSOCIATED);
-	priv->status |= STATUS_DISASSOCIATING;
-
 }
 
 static int ipw_disassociate(void *data)
@@ -7672,6 +7661,8 @@ static int ipw_associate_network(struct 
 	 */
 	priv->channel = network->channel;
 	memcpy(priv->bssid, network->bssid, ETH_ALEN);
+	priv->status |= STATUS_ASSOCIATING;
+	priv->status &= ~STATUS_SECURITY_UPDATED;
 
 	priv->assoc_network = network;
 
@@ -7685,9 +7676,6 @@ static int ipw_associate_network(struct 
 		return err;
 	}
 
-	priv->status |= STATUS_ASSOCIATING;
-	priv->status &= ~STATUS_SECURITY_UPDATED;
-
 	IPW_DEBUG(IPW_DL_STATE, "associating: '%s' " MAC_FMT " \n",
 		  escape_essid(priv->essid, priv->essid_len),
 		  MAC_ARG(priv->bssid));
@@ -7791,6 +7779,13 @@ static int ipw_associate(void *data)
 		return 0;
 	}
 
+	if (priv->status & STATUS_DISASSOCIATING) {
+		IPW_DEBUG_ASSOC("Not attempting association (in "
+				"disassociating)\n ");
+		queue_work(priv->workqueue, &priv->associate);
+		return 0;
+	}
+
 	if (!ipw_is_init(priv) || (priv->status & STATUS_SCANNING)) {
 		IPW_DEBUG_ASSOC("Not attempting association (scanning or not "
 				"initialized)\n");
---
0.99.8.GIT


--- NEW FILE 2956-Updated-driver-version-stamps-for-ipw2100-1.1.3-and-ipw2200-1.0.7.txt ---
Subject: [PATCH] Updated driver version stamps for ipw2100 (1.1.3) and ipw2200 (1.0.7)
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1126762962 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2100.c |    2 +-
 drivers/net/wireless/ipw2200.c |    2 +-
 2 files changed, 2 insertions(+), 2 deletions(-)

applies-to: 905710c6c5ad75b90dbb11da009dd064b705c03a
9ef539d0d6fca1cd0b1f9b884be8b92cb80159c9
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 23a74ac..dba1049 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -167,7 +167,7 @@ that only one external action is invoked
 
 #include "ipw2100.h"
 
-#define IPW2100_VERSION "1.1.1"
+#define IPW2100_VERSION "1.1.3"
 
 #define DRV_NAME	"ipw2100"
 #define DRV_VERSION	IPW2100_VERSION
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index a763092..0b1c6fe 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -32,7 +32,7 @@
 
 #include "ipw2200.h"
 
-#define IPW2200_VERSION "1.0.5"
+#define IPW2200_VERSION "1.0.7"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2005 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
---
0.99.8.GIT


--- NEW FILE 2957-Pulled-out-a-stray-KERNEL_VERSION-check-around-the-suspend-handler.txt ---
Subject: [PATCH] Pulled out a stray KERNEL_VERSION check around the suspend handler.
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1126764031 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2100.c |    4 ----
 1 files changed, 0 insertions(+), 4 deletions(-)

applies-to: 3b86e4c0453ac4cd87a2d58378fc531f93c23597
87bb5e3814572b85cf5d4650fb1f88267411845f
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index dba1049..ed4f1a5 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -6709,11 +6709,7 @@ static void __devexit ipw2100_pci_remove
 }
 
 #ifdef CONFIG_PM
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,11)
-static int ipw2100_suspend(struct pci_dev *pci_dev, u32 state)
-#else
 static int ipw2100_suspend(struct pci_dev *pci_dev, pm_message_t state)
-#endif
 {
 	struct ipw2100_priv *priv = pci_get_drvdata(pci_dev);
 	struct net_device *dev = priv->net_dev;
---
0.99.8.GIT


--- NEW FILE 2958-Fix-Driver-using-old-proc-net-wireless-support-please-fix-driver-message.txt ---
Subject: [PATCH] Fix 'Driver using old /proc/net/wireless support, please fix driver !' message.
From: Benoit Boissinot <bboissin+ipw2100 at gmail.com>
Date: 1126805428 +0000

Wireless extensions moved the get_wireless_stats handler from being
in net_device into wireless_handler.

Signed-off-by: Benoit Boissinot <benoit.boissinot at ens-lyon.org>
Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   19 ++++++++++++-------
 drivers/net/wireless/ipw2200.h |    2 ++
 2 files changed, 14 insertions(+), 7 deletions(-)

applies-to: b4e20691e20077eaee00eab3266b32f3c1b7da05
97a78ca968b84a5e9d8854622b4760cec5058f77
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 0b1c6fe..b89ede1 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -125,6 +125,7 @@ static int ipw_send_qos_info_command(str
 				     *qos_param);
 #endif				/* CONFIG_IPW_QOS */
 
+static struct iw_statistics *ipw_get_wireless_stats(struct net_device *dev);
 static void ipw_remove_current_network(struct ipw_priv *priv);
 static void ipw_rx(struct ipw_priv *priv);
 static int ipw_queue_tx_reclaim(struct ipw_priv *priv,
@@ -8883,6 +8884,13 @@ static int ipw_wx_get_range(struct net_d
 	range->num_frequency = i;
 
 	up(&priv->sem);
+
+	/* Event capability (kernel + driver) */
+	range->event_capa[0] = (IW_EVENT_CAPA_K_0 |
+				IW_EVENT_CAPA_MASK(SIOCGIWTHRSPY) |
+				IW_EVENT_CAPA_MASK(SIOCGIWAP));
+	range->event_capa[1] = IW_EVENT_CAPA_K_1;
+
 	IPW_DEBUG_WX("GET Range\n");
 	return 0;
 }
@@ -9999,10 +10007,9 @@ static struct iw_handler_def ipw_wx_hand
 	.num_private_args = ARRAY_SIZE(ipw_priv_args),
 	.private = ipw_priv_handler,
 	.private_args = ipw_priv_args,
+	.get_wireless_stats = ipw_get_wireless_stats,
 };
 
-static struct iw_public_data ipw_wx_data;
-
 /*
  * Get wireless statistics.
  * Called by /proc/net/wireless
@@ -11487,9 +11494,6 @@ static int ipw_pci_probe(struct pci_dev 
 	SET_MODULE_OWNER(net_dev);
 	SET_NETDEV_DEV(net_dev, &pdev->dev);
 
-	ipw_wx_data.spy_data = &priv->ieee->spy_data;
-	ipw_wx_data.ieee80211 = priv->ieee;
-
 	down(&priv->sem);
 
 	priv->ieee->hard_start_xmit = ipw_net_hard_start_xmit;
@@ -11514,8 +11518,9 @@ static int ipw_pci_probe(struct pci_dev 
 	net_dev->get_stats = ipw_net_get_stats;
 	net_dev->set_multicast_list = ipw_net_set_multicast_list;
 	net_dev->set_mac_address = ipw_net_set_mac_address;
-	net_dev->get_wireless_stats = ipw_get_wireless_stats;
-	net_dev->wireless_data = &ipw_wx_data;
+	priv->wireless_data.spy_data = &priv->ieee->spy_data;
+	priv->wireless_data.ieee80211 = priv->ieee;
+	net_dev->wireless_data = &priv->wireless_data;
 	net_dev->wireless_handlers = &ipw_wx_handler_def;
 	net_dev->ethtool_ops = &ipw_ethtool_ops;
 	net_dev->irq = pdev->irq;
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 28f1216..3e76994 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -1228,6 +1228,8 @@ struct ipw_priv {
 
 	struct iw_statistics wstats;
 
+	struct iw_public_data wireless_data;
+
 	struct workqueue_struct *workqueue;
 
 	struct work_struct adhoc_check;
---
0.99.8.GIT


--- NEW FILE 2959-Removed-legacy-WIRELESS_EXT-checks-from-ipw2200.c.txt ---
Subject: [PATCH] Removed legacy WIRELESS_EXT checks from ipw2200.c
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1128545948 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |  508 ----------------------------------------
 1 files changed, 1 insertions(+), 507 deletions(-)

applies-to: 79a8105f17bab5db404d1f9bd49b3fa916fd1eb1
8935f39e86e3707770e091fb58d9060307edf959
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index b89ede1..8e17308 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -6159,70 +6159,6 @@ static void ipw_bg_abort_scan(void *data
 	up(&priv->sem);
 }
 
-#if WIRELESS_EXT < 18
-/* Support for wpa_supplicant before WE-18, deprecated. */
-
-/* following definitions must match definitions in driver_ipw.c */
-
-#define IPW_IOCTL_WPA_SUPPLICANT		SIOCIWFIRSTPRIV+30
-
-#define IPW_CMD_SET_WPA_PARAM			1
-#define	IPW_CMD_SET_WPA_IE			2
-#define IPW_CMD_SET_ENCRYPTION			3
-#define IPW_CMD_MLME				4
-
-#define IPW_PARAM_WPA_ENABLED			1
-#define IPW_PARAM_TKIP_COUNTERMEASURES		2
-#define IPW_PARAM_DROP_UNENCRYPTED		3
-#define IPW_PARAM_PRIVACY_INVOKED		4
-#define IPW_PARAM_AUTH_ALGS			5
-#define IPW_PARAM_IEEE_802_1X			6
-
-#define IPW_MLME_STA_DEAUTH			1
-#define IPW_MLME_STA_DISASSOC			2
-
-#define IPW_CRYPT_ERR_UNKNOWN_ALG		2
-#define IPW_CRYPT_ERR_UNKNOWN_ADDR		3
-#define IPW_CRYPT_ERR_CRYPT_INIT_FAILED		4
-#define IPW_CRYPT_ERR_KEY_SET_FAILED		5
-#define IPW_CRYPT_ERR_TX_KEY_SET_FAILED		6
-#define IPW_CRYPT_ERR_CARD_CONF_FAILED		7
-
-#define	IPW_CRYPT_ALG_NAME_LEN			16
-
-struct ipw_param {
-	u32 cmd;
-	u8 sta_addr[ETH_ALEN];
-	union {
-		struct {
-			u8 name;
-			u32 value;
-		} wpa_param;
-		struct {
-			u32 len;
-			u8 reserved[32];
-			u8 data[0];
-		} wpa_ie;
-		struct {
-			u32 command;
-			u32 reason_code;
-		} mlme;
-		struct {
-			u8 alg[IPW_CRYPT_ALG_NAME_LEN];
-			u8 set_tx;
-			u32 err;
-			u8 idx;
-			u8 seq[8];	/* sequence counter (set: RX, get: TX) */
-			u16 key_len;
-			u8 key[0];
-		} crypt;
-
-	} u;
-};
-
-/* end of driver_ipw.c code */
-#endif
-
 static int ipw_wpa_enable(struct ipw_priv *priv, int value)
 {
 	/* This is called when wpa_supplicant loads and closes the driver
@@ -6231,11 +6167,6 @@ static int ipw_wpa_enable(struct ipw_pri
 	return 0;
 }
 
-#if WIRELESS_EXT < 18
-#define IW_AUTH_ALG_OPEN_SYSTEM			0x1
-#define IW_AUTH_ALG_SHARED_KEY			0x2
-#endif
-
 static int ipw_wpa_set_auth_algs(struct ipw_priv *priv, int value)
 {
 	struct ieee80211_device *ieee = priv->ieee;
@@ -6283,416 +6214,6 @@ static int ipw_set_rsn_capa(struct ipw_p
 	return ipw_send_cmd(priv, &cmd);
 }
 
-#if WIRELESS_EXT < 18
-static int ipw_wpa_set_param(struct net_device *dev, u8 name, u32 value)
-{
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_crypt_data *crypt;
-	unsigned long flags;
-	int ret = 0;
-
-	switch (name) {
-	case IPW_PARAM_WPA_ENABLED:
-		ret = ipw_wpa_enable(priv, value);
-		break;
-
-	case IPW_PARAM_TKIP_COUNTERMEASURES:
-		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
-		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
-			IPW_WARNING("Can't set TKIP countermeasures: "
-				    "crypt not set!\n");
-			break;
-		}
-
-		flags = crypt->ops->get_flags(crypt->priv);
-
-		if (value)
-			flags |= IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
-		else
-			flags &= ~IEEE80211_CRYPTO_TKIP_COUNTERMEASURES;
-
-		crypt->ops->set_flags(flags, crypt->priv);
-
-		break;
-
-	case IPW_PARAM_DROP_UNENCRYPTED:{
-			/* HACK:
-			 *
-			 * wpa_supplicant calls set_wpa_enabled when the driver
-			 * is loaded and unloaded, regardless of if WPA is being
-			 * used.  No other calls are made which can be used to
-			 * determine if encryption will be used or not prior to
-			 * association being expected.  If encryption is not being
-			 * used, drop_unencrypted is set to false, else true -- we
-			 * can use this to determine if the CAP_PRIVACY_ON bit should
-			 * be set.
-			 */
-			struct ieee80211_security sec = {
-				.flags = SEC_ENABLED,
-				.enabled = value,
-			};
-			priv->ieee->drop_unencrypted = value;
-			/* We only change SEC_LEVEL for open mode. Others
-			 * are set by ipw_wpa_set_encryption.
-			 */
-			if (!value) {
-				sec.flags |= SEC_LEVEL;
-				sec.level = SEC_LEVEL_0;
-			} else {
-				sec.flags |= SEC_LEVEL;
-				sec.level = SEC_LEVEL_1;
-			}
-			if (priv->ieee->set_security)
-				priv->ieee->set_security(priv->ieee->dev, &sec);
-			break;
-		}
-
-	case IPW_PARAM_PRIVACY_INVOKED:
-		priv->ieee->privacy_invoked = value;
-		break;
-
-	case IPW_PARAM_AUTH_ALGS:
-		ret = ipw_wpa_set_auth_algs(priv, value);
-		break;
-
-	case IPW_PARAM_IEEE_802_1X:
-		priv->ieee->ieee802_1x = value;
-		break;
-
-	default:
-		IPW_ERROR("%s: Unknown WPA param: %d\n", dev->name, name);
-		ret = -EOPNOTSUPP;
-	}
-
-	return ret;
-}
-
-static int ipw_wpa_mlme(struct net_device *dev, int command, int reason)
-{
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	int ret = 0;
-
-	switch (command) {
-	case IPW_MLME_STA_DEAUTH:
-		// silently ignore
-		break;
-
-	case IPW_MLME_STA_DISASSOC:
-		ipw_disassociate(priv);
-		break;
-
-	default:
-		IPW_ERROR("%s: Unknown MLME request: %d\n", dev->name, command);
-		ret = -EOPNOTSUPP;
-	}
-
-	return ret;
-}
-
-static int ipw_wpa_ie_cipher2level(u8 cipher)
-{
-	switch (cipher) {
-	case 4:		/* CCMP */
-		return SEC_LEVEL_3;
-	case 2:		/* TKIP */
-		return SEC_LEVEL_2;
-	case 5:		/* WEP104 */
-	case 1:		/* WEP40 */
-		return SEC_LEVEL_1;
-	case 0:		/* NONE */
-		return SEC_LEVEL_0;
-	default:
-		return -1;
-	}
-}
-
-static int ipw_wpa_set_wpa_ie(struct net_device *dev,
-			      struct ipw_param *param, int plen)
-{
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
-	u8 *buf;
-	u8 *ptk, *gtk;
-	int level;
-
-	if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
-	    (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
-		return -EINVAL;
-
-	if (param->u.wpa_ie.len) {
-		buf = kmalloc(param->u.wpa_ie.len, GFP_KERNEL);
-		if (buf == NULL)
-			return -ENOMEM;
-
-		memcpy(buf, param->u.wpa_ie.data, param->u.wpa_ie.len);
-		kfree(ieee->wpa_ie);
-		ieee->wpa_ie = buf;
-		ieee->wpa_ie_len = param->u.wpa_ie.len;
-	} else {
-		kfree(ieee->wpa_ie);
-		ieee->wpa_ie = NULL;
-		ieee->wpa_ie_len = 0;
-		goto done;
-	}
-
-	if (priv->ieee->host_encrypt)
-		goto done;
-
-	/* HACK: Parse wpa_ie here to get pairwise suite, otherwise
-	 * we need to change driver_ipw.c from wpa_supplicant. This
-	 * is OK since -Dipw is deprecated. The -Dwext driver has a
-	 * clean way to handle this. */
-	gtk = ptk = (u8 *) ieee->wpa_ie;
-	if (ieee->wpa_ie[0] == 0x30) {	/* RSN IE */
-		gtk += 4 + 3;
-		ptk += 4 + 4 + 2 + 3;
-	} else {		/* WPA IE */
-		gtk += 8 + 3;
-		ptk += 8 + 4 + 2 + 3;
-	}
-
-	if (ptk - (u8 *) ieee->wpa_ie > ieee->wpa_ie_len)
-		return -EINVAL;
-
-	level = ipw_wpa_ie_cipher2level(*gtk);
-	ipw_set_hw_decrypt_multicast(priv, level);
-
-	level = ipw_wpa_ie_cipher2level(*ptk);
-	ipw_set_hw_decrypt_unicast(priv, level);
-
-      done:
-	ipw_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len);
-	return 0;
-}
-
-/* implementation borrowed from hostap driver */
-
-static int ipw_wpa_set_encryption(struct net_device *dev,
-				  struct ipw_param *param, int param_len)
-{
-	int ret = 0;
-	int group_key = 0;
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	struct ieee80211_device *ieee = priv->ieee;
-	struct ieee80211_crypto_ops *ops;
-	struct ieee80211_crypt_data **crypt;
-
-	struct ieee80211_security sec = {
-		.flags = 0,
-	};
-
-	param->u.crypt.err = 0;
-	param->u.crypt.alg[IPW_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
-	if (param_len !=
-	    (int)((char *)param->u.crypt.key - (char *)param) +
-	    param->u.crypt.key_len) {
-		IPW_DEBUG_INFO("Len mismatch %d, %d\n", param_len,
-			       param->u.crypt.key_len);
-		return -EINVAL;
-	}
-	if (param->sta_addr[0] == 0xff && param->sta_addr[1] == 0xff &&
-	    param->sta_addr[2] == 0xff && param->sta_addr[3] == 0xff &&
-	    param->sta_addr[4] == 0xff && param->sta_addr[5] == 0xff) {
-		if (param->u.crypt.idx >= WEP_KEYS)
-			return -EINVAL;
-		crypt = &ieee->crypt[param->u.crypt.idx];
-	} else {
-		return -EINVAL;
-	}
-
-	if (param->u.crypt.idx != 0)
-		group_key = 1;
-
-	sec.flags |= SEC_ENABLED | SEC_ENCRYPT;
-	if (strcmp(param->u.crypt.alg, "none") == 0) {
-		if (crypt) {
-			sec.enabled = 0;
-			sec.encrypt = 0;
-			sec.level = SEC_LEVEL_0;
-			sec.flags |= SEC_LEVEL;
-			ieee80211_crypt_delayed_deinit(ieee, crypt);
-		}
-		goto done;
-	}
-	sec.enabled = 1;
-	sec.encrypt = 1;
-
-	/* IPW HW cannot build TKIP MIC, host decryption still needed. */
-	if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
-		if (group_key)
-			ieee->host_mc_decrypt = 1;
-		else
-			ieee->host_encrypt_msdu = 1;
-	}
-
-	/*if (!(ieee->host_encrypt || ieee->host_encrypt_msdu ||
-	   ieee->host_decrypt))
-	   goto skip_host_crypt; */
-	if (group_key ? !ieee->host_mc_decrypt :
-	    !(ieee->host_encrypt || ieee->host_decrypt ||
-	      ieee->host_encrypt_msdu))
-		goto skip_host_crypt;
-
-	ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0) {
-		request_module("ieee80211_crypt_wep");
-		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	} else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0) {
-		request_module("ieee80211_crypt_tkip");
-		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	} else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0) {
-		request_module("ieee80211_crypt_ccmp");
-		ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
-	}
-	if (ops == NULL) {
-		IPW_DEBUG_INFO("%s: unknown crypto alg '%s'\n",
-			       dev->name, param->u.crypt.alg);
-		param->u.crypt.err = IPW_CRYPT_ERR_UNKNOWN_ALG;
-		ret = -EINVAL;
-		goto done;
-	}
-
-	if (*crypt == NULL || (*crypt)->ops != ops) {
-		struct ieee80211_crypt_data *new_crypt;
-
-		ieee80211_crypt_delayed_deinit(ieee, crypt);
-
-		new_crypt = (struct ieee80211_crypt_data *)
-		    kmalloc(sizeof(*new_crypt), GFP_KERNEL);
-		if (new_crypt == NULL) {
-			ret = -ENOMEM;
-			goto done;
-		}
-		memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
-		new_crypt->ops = ops;
-		if (new_crypt->ops && try_module_get(new_crypt->ops->owner))
-			new_crypt->priv =
-			    new_crypt->ops->init(param->u.crypt.idx);
-
-		if (new_crypt->priv == NULL) {
-			kfree(new_crypt);
-			param->u.crypt.err = IPW_CRYPT_ERR_CRYPT_INIT_FAILED;
-			ret = -EINVAL;
-			goto done;
-		}
-
-		*crypt = new_crypt;
-	}
-
-	if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
-	    (*crypt)->ops->set_key(param->u.crypt.key,
-				   param->u.crypt.key_len, param->u.crypt.seq,
-				   (*crypt)->priv) < 0) {
-		IPW_DEBUG_INFO("%s: key setting failed\n", dev->name);
-		param->u.crypt.err = IPW_CRYPT_ERR_KEY_SET_FAILED;
-		ret = -EINVAL;
-		goto done;
-	}
-
-      skip_host_crypt:
-	if (param->u.crypt.set_tx) {
-		ieee->tx_keyidx = param->u.crypt.idx;
-		sec.active_key = param->u.crypt.idx;
-		sec.flags |= SEC_ACTIVE_KEY;
-	} else
-		sec.flags &= ~SEC_ACTIVE_KEY;
-
-	if (param->u.crypt.alg != NULL) {
-		memcpy(sec.keys[param->u.crypt.idx],
-		       param->u.crypt.key, param->u.crypt.key_len);
-		sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
-		sec.flags |= (1 << param->u.crypt.idx);
-
-		if (strcmp(param->u.crypt.alg, "WEP") == 0) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_1;
-		} else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_2;
-		} else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
-			sec.flags |= SEC_LEVEL;
-			sec.level = SEC_LEVEL_3;
-		}
-		/* Don't set sec level for group keys. */
-		if (group_key)
-			sec.flags &= ~SEC_LEVEL;
-	}
-      done:
-	if (ieee->set_security)
-		ieee->set_security(ieee->dev, &sec);
-
-	/* Do not reset port if card is in Managed mode since resetting will
-	 * generate new IEEE 802.11 authentication which may end up in looping
-	 * with IEEE 802.1X.  If your hardware requires a reset after WEP
-	 * configuration (for example... Prism2), implement the reset_port in
-	 * the callbacks structures used to initialize the 802.11 stack. */
-	if (ieee->reset_on_keychange &&
-	    ieee->iw_mode != IW_MODE_INFRA &&
-	    ieee->reset_port && ieee->reset_port(dev)) {
-		IPW_DEBUG_INFO("%s: reset_port failed\n", dev->name);
-		param->u.crypt.err = IPW_CRYPT_ERR_CARD_CONF_FAILED;
-		return -EINVAL;
-	}
-
-	return ret;
-}
-
-static int ipw_wpa_supplicant(struct net_device *dev, struct iw_point *p)
-{
-	struct ipw_param *param;
-	struct ipw_priv *priv = ieee80211_priv(dev);
-	int ret = 0;
-
-	IPW_DEBUG_INFO("wpa_supplicant: len=%d\n", p->length);
-
-	if (p->length < sizeof(struct ipw_param) || !p->pointer)
-		return -EINVAL;
-
-	param = (struct ipw_param *)kmalloc(p->length, GFP_KERNEL);
-	if (param == NULL)
-		return -ENOMEM;
-
-	if (copy_from_user(param, p->pointer, p->length)) {
-		kfree(param);
-		return -EFAULT;
-	}
-
-	down(&priv->sem);
-	switch (param->cmd) {
-
-	case IPW_CMD_SET_WPA_PARAM:
-		ret = ipw_wpa_set_param(dev, param->u.wpa_param.name,
-					param->u.wpa_param.value);
-		break;
-
-	case IPW_CMD_SET_WPA_IE:
-		ret = ipw_wpa_set_wpa_ie(dev, param, p->length);
-		break;
-
-	case IPW_CMD_SET_ENCRYPTION:
-		ret = ipw_wpa_set_encryption(dev, param, p->length);
-		break;
-
-	case IPW_CMD_MLME:
-		ret = ipw_wpa_mlme(dev, param->u.mlme.command,
-				   param->u.mlme.reason_code);
-		break;
-
-	default:
-		IPW_ERROR("%s: Unknown WPA supplicant request: %d\n",
-			  dev->name, param->cmd);
-		ret = -EOPNOTSUPP;
-	}
-
-	up(&priv->sem);
-	if (ret == 0 && copy_to_user(p->pointer, param, p->length))
-		ret = -EFAULT;
-
-	kfree(param);
-	return ret;
-}
-#else
 /*
  * WE-18 support
  */
@@ -7021,7 +6542,6 @@ static int ipw_wx_set_mlme(struct net_de
 	}
 	return 0;
 }
-#endif
 
 #ifdef CONFIG_IPW_QOS
 
@@ -9391,7 +8911,6 @@ static int ipw_wx_get_retry(struct net_d
 	return 0;
 }
 
-#if WIRELESS_EXT > 17
 static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid,
 				   int essid_len)
 {
@@ -9455,14 +8974,12 @@ static int ipw_request_direct_scan(struc
 	up(&priv->sem);
 	return err;
 }
-#endif				/* WIRELESS_EXT > 17 */
 
 static int ipw_wx_set_scan(struct net_device *dev,
 			   struct iw_request_info *info,
 			   union iwreq_data *wrqu, char *extra)
 {
 	struct ipw_priv *priv = ieee80211_priv(dev);
-#if WIRELESS_EXT > 17
 	struct iw_scan_req *req = NULL;
 	if (wrqu->data.length
 	    && wrqu->data.length == sizeof(struct iw_scan_req)) {
@@ -9473,7 +8990,7 @@ static int ipw_wx_set_scan(struct net_de
 			return 0;
 		}
 	}
-#endif
+
 	IPW_DEBUG_WX("Start scan\n");
 
 	queue_work(priv->workqueue, &priv->request_scan);
@@ -9923,7 +9440,6 @@ static iw_handler ipw_wx_handlers[] = {
 	IW_IOCTL(SIOCGIWSPY) = iw_handler_get_spy,
 	IW_IOCTL(SIOCSIWTHRSPY) = iw_handler_set_thrspy,
 	IW_IOCTL(SIOCGIWTHRSPY) = iw_handler_get_thrspy,
-#if WIRELESS_EXT > 17
 	IW_IOCTL(SIOCSIWGENIE) = ipw_wx_set_genie,
 	IW_IOCTL(SIOCGIWGENIE) = ipw_wx_get_genie,
 	IW_IOCTL(SIOCSIWMLME) = ipw_wx_set_mlme,
@@ -9931,7 +9447,6 @@ static iw_handler ipw_wx_handlers[] = {
 	IW_IOCTL(SIOCGIWAUTH) = ipw_wx_get_auth,
 	IW_IOCTL(SIOCSIWENCODEEXT) = ipw_wx_set_encodeext,
 	IW_IOCTL(SIOCGIWENCODEEXT) = ipw_wx_get_encodeext,
-#endif
 };
 
 enum {
@@ -11317,24 +10832,6 @@ static void ipw_bg_down(void *data)
 	up(&priv->sem);
 }
 
-#if WIRELESS_EXT < 18
-static int ipw_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
-	struct iwreq *wrq = (struct iwreq *)rq;
-	int ret = -1;
-	switch (cmd) {
-	case IPW_IOCTL_WPA_SUPPLICANT:
-		ret = ipw_wpa_supplicant(dev, &wrq->u.data);
-		return ret;
-
-	default:
-		return -EOPNOTSUPP;
-	}
-
-	return -EOPNOTSUPP;
-}
-#endif
-
 /* Called by register_netdev() */
 static int ipw_net_init(struct net_device *dev)
 {
@@ -11512,9 +11009,6 @@ static int ipw_pci_probe(struct pci_dev 
 	net_dev->open = ipw_net_open;
 	net_dev->stop = ipw_net_stop;
 	net_dev->init = ipw_net_init;
-#if WIRELESS_EXT < 18
-	net_dev->do_ioctl = ipw_ioctl;
-#endif
 	net_dev->get_stats = ipw_net_get_stats;
 	net_dev->set_multicast_list = ipw_net_set_multicast_list;
 	net_dev->set_mac_address = ipw_net_set_mac_address;
---
0.99.8.GIT


--- NEW FILE 2960-Fixes-missed-beacon-logic-in-relation-to-on-network-AP-roaming.txt ---
Subject: [PATCH] Fixes missed beacon logic in relation to on-network AP roaming.
From: Ben Cahill <ben.m.cahill at intel.com>
Date: 1128630881 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   27 ++++++++++++++++++++-------
 drivers/net/wireless/ipw2200.h |    3 +++
 2 files changed, 23 insertions(+), 7 deletions(-)

applies-to: d85da62867f9d46fe68baed98186a4f04bb787ae
e758256104c3c2475f7746bc1b348c99cdb207f2
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 8e17308..8941929 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -4082,6 +4082,11 @@ static void ipw_bg_gather_stats(void *da
 	up(&priv->sem);
 }
 
+/* Missed beacon behavior:
+ * 1st missed -> roaming_threshold, just wait, don't do any scan/roam.
+ * roaming_threshold -> disassociate_threshold, scan and roam for better signal.
+ * Above disassociate threshold, give up and stop scanning.
+ * Roaming is disabled if disassociate_threshold <= roaming_threshold  */
 static inline void ipw_handle_missed_beacon(struct ipw_priv *priv,
 					    int missed_count)
 {
@@ -4116,9 +4121,12 @@ static inline void ipw_handle_missed_bea
 		return;
 	}
 
-	if (missed_count > priv->roaming_threshold) {
+	if (missed_count > priv->roaming_threshold &&
+	    missed_count <= priv->disassociate_threshold) {
 		/* If we are not already roaming, set the ROAM
-		 * bit in the status and kick off a scan */
+		 * bit in the status and kick off a scan.
+		 * This can happen several times before we reach
+		 * disassociate_threshold. */
 		IPW_DEBUG(IPW_DL_NOTIF | IPW_DL_STATE,
 			  "Missed beacon: %d - initiate "
 			  "roaming\n", missed_count);
@@ -4480,11 +4488,16 @@ static inline void ipw_rx_notification(s
 					      STATUS_DISASSOCIATING)))
 				queue_work(priv->workqueue, &priv->associate);
 			else if (priv->status & STATUS_ROAMING) {
-				/* If a scan completed and we are in roam mode, then
-				 * the scan that completed was the one requested as a
-				 * result of entering roam... so, schedule the
-				 * roam work */
-				queue_work(priv->workqueue, &priv->roam);
+				if (x->status == SCAN_COMPLETED_STATUS_COMPLETE)
+					/* If a scan completed and we are in roam mode, then
+					 * the scan that completed was the one requested as a
+					 * result of entering roam... so, schedule the
+					 * roam work */
+					queue_work(priv->workqueue,
+						   &priv->roam);
+				else
+					/* Don't schedule if we aborted the scan */
+					priv->status &= ~STATUS_ROAMING;
 			} else if (priv->status & STATUS_SCAN_PENDING)
 				queue_work(priv->workqueue,
 					   &priv->request_scan);
diff --git a/drivers/net/wireless/ipw2200.h b/drivers/net/wireless/ipw2200.h
index 3e76994..617ec4d 100644
--- a/drivers/net/wireless/ipw2200.h
+++ b/drivers/net/wireless/ipw2200.h
@@ -590,6 +590,9 @@ struct notif_channel_result {
 	u8 uReserved;
 } __attribute__ ((packed));
 
+#define SCAN_COMPLETED_STATUS_COMPLETE  1
+#define SCAN_COMPLETED_STATUS_ABORTED   2
+
 struct notif_scan_complete {
 	u8 scan_type;
 	u8 num_channels;
---
0.99.8.GIT


--- NEW FILE 2961-Removed-warning-about-TKIP-not-being-configured-if-countermeasures-are.txt ---
Subject: [PATCH] Removed warning about TKIP not being configured if countermeasures are
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1129195608 +0000
configured.

Countermeasures default to being turned off when wpa_supplicant runs,
regardless of if TKIP is being used.  They are only turned on if a TKIP
is running.  The warning we were printing is therefore not needed.

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2100.c |   10 ++--------
 drivers/net/wireless/ipw2200.c |   10 ++--------
 2 files changed, 4 insertions(+), 16 deletions(-)

applies-to: c3076d27876f5d633db3ed5f8e3e4775679b7245
991d1cc5963f4926478f3139ec0b0dd26a2c888c
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index ed4f1a5..76841cb 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -5866,11 +5866,8 @@ static int ipw2100_wpa_set_param(struct 
 
 	case IPW2100_PARAM_TKIP_COUNTERMEASURES:
 		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
-		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
-			IPW_DEBUG_WARNING("Can't set TKIP countermeasures: "
-					  "crypt not set!\n");
+		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
 			break;
-		}
 
 		flags = crypt->ops->get_flags(crypt->priv);
 
@@ -7935,11 +7932,8 @@ static int ipw2100_wx_set_auth(struct ne
 
 	case IW_AUTH_TKIP_COUNTERMEASURES:
 		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
-		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
-			IPW_DEBUG_WARNING("Can't set TKIP countermeasures: "
-					  "crypt not set!\n");
+		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
 			break;
-		}
 
 		flags = crypt->ops->get_flags(crypt->priv);
 
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 8941929..750e43e 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -6357,11 +6357,8 @@ static int ipw_wx_set_auth(struct net_de
 
 	case IW_AUTH_TKIP_COUNTERMEASURES:
 		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
-		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) {
-			IPW_WARNING("Can't set TKIP countermeasures: "
-				    "crypt not set!\n");
+		if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags)
 			break;
-		}
 
 		flags = crypt->ops->get_flags(crypt->priv);
 
@@ -6453,11 +6450,8 @@ static int ipw_wx_get_auth(struct net_de
 
 	case IW_AUTH_TKIP_COUNTERMEASURES:
 		crypt = priv->ieee->crypt[priv->ieee->tx_keyidx];
-		if (!crypt || !crypt->ops->get_flags) {
-			IPW_WARNING("Can't get TKIP countermeasures: "
-				    "crypt not set!\n");
+		if (!crypt || !crypt->ops->get_flags)
 			break;
-		}
 
 		param->value = (crypt->ops->get_flags(crypt->priv) &
 				IEEE80211_CRYPTO_TKIP_COUNTERMEASURES) ? 1 : 0;
---
0.99.8.GIT


--- NEW FILE 2962-Added-channel-support-for-ipw2200-cards-identified-as-ZZR.txt ---
Subject: [PATCH] Added channel support for ipw2200 cards identified as 'ZZR'
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1129756351 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |   18 +++++++++++++++++-
 1 files changed, 17 insertions(+), 1 deletions(-)

applies-to: dcfb9b32f23be2c8952797fd81174219abd76c85
035205760e4f28082fedb258a20c804746c84ffe
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 750e43e..081957a 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -10495,6 +10495,17 @@ static const struct ieee80211_geo ipw_ge
 	       {5210, 42}, {5230, 46}},
 	 },
 
+	{			/* Rest of World */
+	 "ZZR",
+	 .bg_channels = 14,
+	 .bg = {{2412, 1}, {2417, 2}, {2422, 3},
+		{2427, 4}, {2432, 5}, {2437, 6},
+		{2442, 7}, {2447, 8}, {2452, 9},
+		{2457, 10}, {2462, 11}, {2467, 12},
+		{2472, 13}, {2484, 14, IEEE80211_CH_B_ONLY |
+			     IEEE80211_CH_PASSIVE_ONLY}},
+	 },
+
 	{			/* High Band */
 	 "ZZH",
 	 .bg_channels = 13,
@@ -10711,8 +10722,13 @@ static int ipw_up(struct ipw_priv *priv)
 				    ipw_geos[j].name, 3))
 				break;
 		}
-		if (j == ARRAY_SIZE(ipw_geos))
+		if (j == ARRAY_SIZE(ipw_geos)) {
+			IPW_WARNING("SKU [%c%c%c] not recognized.\n",
+				    priv->eeprom[EEPROM_COUNTRY_CODE + 0],
+				    priv->eeprom[EEPROM_COUNTRY_CODE + 1],
+				    priv->eeprom[EEPROM_COUNTRY_CODE + 2]);
 			j = 0;
+		}
 		if (ipw_set_geo(priv->ieee, &ipw_geos[j])) {
 			IPW_WARNING("Could not set geography.");
 			return 0;
---
0.99.8.GIT


--- NEW FILE 2963-Fixed-problem-with-not-being-able-to-send-broadcast-packets.txt ---
Subject: [PATCH] Fixed problem with not being able to send broadcast packets.
From: Hong Liu <hong.liu at intel.com>
Date: 1129757133 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |    9 ++++++---
 1 files changed, 6 insertions(+), 3 deletions(-)

applies-to: 5d13b9c6287f1e6f753f859026920e9c67f53689
9d5b880bb8e977426d64a4caebe3fd3ae73a2862
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 081957a..c1ae6d4 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -7456,7 +7456,8 @@ static void ipw_handle_data_packet(struc
 	/* HW decrypt will not clear the WEP bit, MIC, PN, etc. */
 	hdr = (struct ieee80211_hdr_4addr *)rxb->skb->data;
 	if (priv->ieee->iw_mode != IW_MODE_MONITOR &&
-	    (is_multicast_ether_addr(hdr->addr1) ?
+	    ((is_multicast_ether_addr(hdr->addr1) ||
+	      is_broadcast_ether_addr(hdr->addr1)) ?
 	     !priv->ieee->host_mc_decrypt : !priv->ieee->host_decrypt))
 		ipw_rebuild_decrypted_skb(priv, rxb->skb);
 
@@ -9652,7 +9653,8 @@ static inline int ipw_tx_skb(struct ipw_
 	switch (priv->ieee->iw_mode) {
 	case IW_MODE_ADHOC:
 		hdr_len = IEEE80211_3ADDR_LEN;
-		unicast = !is_multicast_ether_addr(hdr->addr1);
+		unicast = !(is_multicast_ether_addr(hdr->addr1) ||
+			    is_broadcast_ether_addr(hdr->addr1));
 		id = ipw_find_station(priv, hdr->addr1);
 		if (id == IPW_INVALID_STATION) {
 			id = ipw_add_station(priv, hdr->addr1);
@@ -9667,7 +9669,8 @@ static inline int ipw_tx_skb(struct ipw_
 
 	case IW_MODE_INFRA:
 	default:
-		unicast = !is_multicast_ether_addr(hdr->addr3);
+		unicast = !(is_multicast_ether_addr(hdr->addr3) ||
+			    is_broadcast_ether_addr(hdr->addr3));
 		hdr_len = IEEE80211_3ADDR_LEN;
 		id = 0;
 		break;
---
0.99.8.GIT


--- NEW FILE 2964-Fixed-parameter-reordering-in-firmware-log-routine.txt ---
Subject: [PATCH] Fixed parameter reordering in firmware log routine.
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1125416065 -0500

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: eabb0466805d6e13268951f50edf331ffee526a5
286568ab1e8f0e09a76cfa58e8ed48ddc44484b5
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index c1ae6d4..f49b012 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -526,7 +526,7 @@ static void ipw_dump_error_log(struct ip
 	for (i = 0; i < error->log_len; i++)
 		IPW_ERROR("%i\t0x%08x\t%i\n",
 			  error->log[i].time,
-			  error->log[i].event, error->log[i].data);
+			  error->log[i].data, error->log[i].event);
 }
 #endif
 
---
0.99.8.GIT


--- NEW FILE 2965-Updated-firmware-version-stamp-to-2.4-from-2.3-so-it-will-use-the-latest-firmware.txt ---
Subject: [PATCH] Updated firmware version stamp to 2.4 from 2.3 so it will use the latest firmware.
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1124951848 -0500
You can obtain the firmware at http://ipw2200.sf.net/firmware.php

Signed-off-by: James Ketrenos <jketreno at linux.intel.com>

---

 drivers/net/wireless/ipw2200.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: fbb8bdd43cbc12b642ed4109a8b2de99793e4f47
81715376de909637b957f856e30880871fbd78fc
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index f49b012..56709d2 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -2834,7 +2834,7 @@ struct fw_chunk {
 };
 
 #define IPW_FW_MAJOR_VERSION 2
-#define IPW_FW_MINOR_VERSION 3
+#define IPW_FW_MINOR_VERSION 4
 
 #define IPW_FW_MINOR(x) ((x & 0xff) >> 8)
 #define IPW_FW_MAJOR(x) (x & 0xff)
---
0.99.8.GIT


--- NEW FILE 2966-Update-version-ipw2200-stamp-to-1.0.8.txt ---
Subject: [PATCH] Update version ipw2200 stamp to 1.0.8
From: James Ketrenos <jketreno at linux.intel.com>
Date: 1129844124 -0500

---

 drivers/net/wireless/ipw2200.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 66319480546e4912c9a5a922d6e679e2d5825ad7
cf1b479b6922c6736d9f00d90c2b78e977692c93
diff --git a/drivers/net/wireless/ipw2200.c b/drivers/net/wireless/ipw2200.c
index 56709d2..136884c 100644
--- a/drivers/net/wireless/ipw2200.c
+++ b/drivers/net/wireless/ipw2200.c
@@ -32,7 +32,7 @@
 
 #include "ipw2200.h"
 
-#define IPW2200_VERSION "1.0.7"
+#define IPW2200_VERSION "git-1.0.8"
 #define DRV_DESCRIPTION	"Intel(R) PRO/Wireless 2200/2915 Network Driver"
 #define DRV_COPYRIGHT	"Copyright(c) 2003-2005 Intel Corporation"
 #define DRV_VERSION     IPW2200_VERSION
---
0.99.8.GIT


--- NEW FILE 3005-bonding-fix-feature-consolidation.txt ---
Subject: [PATCH] bonding: fix feature consolidation
From: Jay Vosburgh <fubar at us.ibm.com>
Date: 1131158745 -0800

This should resolve http://bugzilla.kernel.org/show_bug.cgi?id=5519

The current feature computation loses bits that it doesn't know about,
resulting in an inability to add VLANs and possibly other havoc.
Rewrote function to preserve bits it doesn't know about, remove an
unneeded state variable, and simplify the code.

Signed-off-by: Jay Vosburgh <fubar at us.ibm.com>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/bonding/bond_main.c |   32 +++++++++++---------------------
 drivers/net/bonding/bonding.h   |    7 ++-----
 2 files changed, 13 insertions(+), 26 deletions(-)

applies-to: a3186746e8f248d4e5f06543e8f499209f5e5581
8e3babcd69ec0fde874838e276eb0b211c6a5647
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 8032126..94cec3c 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1604,35 +1604,27 @@ static int bond_sethwaddr(struct net_dev
 	(NETIF_F_SG|NETIF_F_IP_CSUM|NETIF_F_NO_CSUM|NETIF_F_HW_CSUM)
 
 /* 
- * Compute the features available to the bonding device by 
- * intersection of all of the slave devices' BOND_INTERSECT_FEATURES.
- * Call this after attaching or detaching a slave to update the 
- * bond's features.
+ * Compute the common dev->feature set available to all slaves.  Some
+ * feature bits are managed elsewhere, so preserve feature bits set on
+ * master device that are not part of the examined set.
  */
 static int bond_compute_features(struct bonding *bond)
 {
-	int i;
+	unsigned long features = BOND_INTERSECT_FEATURES;
 	struct slave *slave;
 	struct net_device *bond_dev = bond->dev;
-	int features = bond->bond_features;
+	int i;
 
-	bond_for_each_slave(bond, slave, i) {
-		struct net_device * slave_dev = slave->dev;
-		if (i == 0) {
-			features |= BOND_INTERSECT_FEATURES;
-		}
-		features &=
-			~(~slave_dev->features & BOND_INTERSECT_FEATURES);
-	}
+	bond_for_each_slave(bond, slave, i)
+		features &= (slave->dev->features & BOND_INTERSECT_FEATURES);
 
-	/* turn off NETIF_F_SG if we need a csum and h/w can't do it */
 	if ((features & NETIF_F_SG) && 
-		!(features & (NETIF_F_IP_CSUM |
-			      NETIF_F_NO_CSUM |
-			      NETIF_F_HW_CSUM))) {
+	    !(features & (NETIF_F_IP_CSUM |
+			  NETIF_F_NO_CSUM |
+			  NETIF_F_HW_CSUM)))
 		features &= ~NETIF_F_SG;
-	}
 
+	features |= (bond_dev->features & ~BOND_INTERSECT_FEATURES);
 	bond_dev->features = features;
 
 	return 0;
@@ -4561,8 +4553,6 @@ static int __init bond_init(struct net_d
 			       NETIF_F_HW_VLAN_RX |
 			       NETIF_F_HW_VLAN_FILTER);
 
-	bond->bond_features = bond_dev->features;
-
 #ifdef CONFIG_PROC_FS
 	bond_create_proc_entry(bond);
 #endif
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index bbf9da8..1433e91 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -40,8 +40,8 @@
 #include "bond_3ad.h"
 #include "bond_alb.h"
 
-#define DRV_VERSION	"2.6.4"
-#define DRV_RELDATE	"September 26, 2005"
+#define DRV_VERSION	"2.6.5"
+#define DRV_RELDATE	"November 4, 2005"
 #define DRV_NAME	"bonding"
 #define DRV_DESCRIPTION	"Ethernet Channel Bonding Driver"
 
@@ -211,9 +211,6 @@ struct bonding {
 	struct   bond_params params;
 	struct   list_head vlan_list;
 	struct   vlan_group *vlgrp;
-	/* the features the bonding device supports, independently 
-	 * of any slaves */
-	int	 bond_features; 
 };
 
 /**
---
0.99.8.GIT


--- NEW FILE 3007-drivers-net-s2io.c-make-functions-static.txt ---
Subject: [PATCH] drivers/net/s2io.c: make functions static
From: Adrian Bunk <bunk at stusta.de>
Date: 1131238007 +0100

This patch makes needlessly global functions static.

Signed-off-by: Adrian Bunk <bunk at stusta.de>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/s2io.c |   43 +++++++++++++++++++++++--------------------
 1 files changed, 23 insertions(+), 20 deletions(-)

applies-to: f204efafbe99dab92fe25896e98862922aa408d5
ac1f60db6a62c8605b551497c8002ba267ea1f4a
diff --git a/drivers/net/s2io.c b/drivers/net/s2io.c
index 9c49354..9848892 100644
--- a/drivers/net/s2io.c
+++ b/drivers/net/s2io.c
@@ -1532,7 +1532,7 @@ static int init_nic(struct s2io_nic *nic
 #define LINK_UP_DOWN_INTERRUPT		1
 #define MAC_RMAC_ERR_TIMER		2
 
-int s2io_link_fault_indication(nic_t *nic)
+static int s2io_link_fault_indication(nic_t *nic)
 {
 	if (nic->intr_type != INTA)
 		return MAC_RMAC_ERR_TIMER;
@@ -1864,7 +1864,7 @@ static int verify_xena_quiescence(nic_t 
  *
  */
 
-void fix_mac_address(nic_t * sp)
+static void fix_mac_address(nic_t * sp)
 {
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	u64 val64;
@@ -2162,7 +2162,7 @@ int fill_rxd_3buf(nic_t *nic, RxD_t *rxd
  *  SUCCESS on success or an appropriate -ve value on failure.
  */
 
-int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
+static int fill_rx_buffers(struct s2io_nic *nic, int ring_no)
 {
 	struct net_device *dev = nic->dev;
 	struct sk_buff *skb;
@@ -2833,7 +2833,7 @@ static void alarm_intr_handler(struct s2
  *   SUCCESS on success and FAILURE on failure.
  */
 
-int wait_for_cmd_complete(nic_t * sp)
+static int wait_for_cmd_complete(nic_t * sp)
 {
 	XENA_dev_config_t __iomem *bar0 = sp->bar0;
 	int ret = FAILURE, cnt = 0;
@@ -3079,7 +3079,7 @@ int s2io_set_swapper(nic_t * sp)
 	return SUCCESS;
 }
 
-int wait_for_msix_trans(nic_t *nic, int i)
+static int wait_for_msix_trans(nic_t *nic, int i)
 {
 	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
 	u64 val64;
@@ -3118,7 +3118,7 @@ void restore_xmsi_data(nic_t *nic)
 	}
 }
 
-void store_xmsi_data(nic_t *nic)
+static void store_xmsi_data(nic_t *nic)
 {
 	XENA_dev_config_t *bar0 = (XENA_dev_config_t *) nic->bar0;
 	u64 val64, addr, data;
@@ -3290,7 +3290,7 @@ int s2io_enable_msi_x(nic_t *nic)
  *   file on failure.
  */
 
-int s2io_open(struct net_device *dev)
+static int s2io_open(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
 	int err = 0;
@@ -3420,7 +3420,7 @@ hw_init_failed:
  *  file on failure.
  */
 
-int s2io_close(struct net_device *dev)
+static int s2io_close(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
 	int i;
@@ -3469,7 +3469,7 @@ int s2io_close(struct net_device *dev)
  *  0 on success & 1 on failure.
  */
 
-int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
+static int s2io_xmit(struct sk_buff *skb, struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
 	u16 frg_cnt, frg_len, i, queue, queue_len, put_off, get_off;
@@ -3915,7 +3915,7 @@ static void s2io_updt_stats(nic_t *sp)
  *  pointer to the updated net_device_stats structure.
  */
 
-struct net_device_stats *s2io_get_stats(struct net_device *dev)
+static struct net_device_stats *s2io_get_stats(struct net_device *dev)
 {
 	nic_t *sp = dev->priv;
 	mac_info_t *mac_control;
@@ -5108,19 +5108,20 @@ static void s2io_get_ethtool_stats(struc
 	tmp_stats[i++] = stat_info->sw_stat.double_ecc_errs;
 }
 
-int s2io_ethtool_get_regs_len(struct net_device *dev)
+static int s2io_ethtool_get_regs_len(struct net_device *dev)
 {
 	return (XENA_REG_SPACE);
 }
 
 
-u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
+static u32 s2io_ethtool_get_rx_csum(struct net_device * dev)
 {
 	nic_t *sp = dev->priv;
 
 	return (sp->rx_csum);
 }
-int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
+
+static int s2io_ethtool_set_rx_csum(struct net_device *dev, u32 data)
 {
 	nic_t *sp = dev->priv;
 
@@ -5131,17 +5132,19 @@ int s2io_ethtool_set_rx_csum(struct net_
 
 	return 0;
 }
-int s2io_get_eeprom_len(struct net_device *dev)
+
+static int s2io_get_eeprom_len(struct net_device *dev)
 {
 	return (XENA_EEPROM_SPACE);
 }
 
-int s2io_ethtool_self_test_count(struct net_device *dev)
+static int s2io_ethtool_self_test_count(struct net_device *dev)
 {
 	return (S2IO_TEST_LEN);
 }
-void s2io_ethtool_get_strings(struct net_device *dev,
-			      u32 stringset, u8 * data)
+
+static void s2io_ethtool_get_strings(struct net_device *dev,
+				     u32 stringset, u8 * data)
 {
 	switch (stringset) {
 	case ETH_SS_TEST:
@@ -5157,7 +5160,7 @@ static int s2io_ethtool_get_stats_count(
 	return (S2IO_STAT_LEN);
 }
 
-int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
+static int s2io_ethtool_op_set_tx_csum(struct net_device *dev, u32 data)
 {
 	if (data)
 		dev->features |= NETIF_F_IP_CSUM;
@@ -5210,7 +5213,7 @@ static struct ethtool_ops netdev_ethtool
  *  function always return EOPNOTSUPPORTED
  */
 
-int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int s2io_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
 {
 	return -EOPNOTSUPP;
 }
@@ -5226,7 +5229,7 @@ int s2io_ioctl(struct net_device *dev, s
  *   file on failure.
  */
 
-int s2io_change_mtu(struct net_device *dev, int new_mtu)
+static int s2io_change_mtu(struct net_device *dev, int new_mtu)
 {
 	nic_t *sp = dev->priv;
 
---
0.99.8.GIT


--- NEW FILE 3008-prism54-Unused-variable-extraneous-udelay.txt ---
Subject: [PATCH] prism54 : Unused variable / extraneous udelay
From: Roger While <simrw at sim-basis.de>
Date: 1131393478 +0100

In isl_38xx.c :
The variable "counter" is defined and incremented but never
used except if the driver is hand-compiled setting
VERBOSE > SHOW_ERROR_MESSAGES.
Move the definition and the increment to within the
#if VERBOSE ..   block.

Remove extraneous udelay's.
These are not required when triggering the device.

Signed-off-by: Roger While <simrw at sim-basis.de>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/wireless/prism54/isl_38xx.c |   12 ++++--------
 1 files changed, 4 insertions(+), 8 deletions(-)

applies-to: 8c037f61a24d10678a3b7d1eacebac3b23b00d6b
de7fe963b123365a27f82330689806226a48d088
diff --git a/drivers/net/wireless/prism54/isl_38xx.c b/drivers/net/wireless/prism54/isl_38xx.c
index adc7499..866c476 100644
--- a/drivers/net/wireless/prism54/isl_38xx.c
+++ b/drivers/net/wireless/prism54/isl_38xx.c
@@ -112,9 +112,10 @@ isl38xx_handle_wakeup(isl38xx_control_bl
 void
 isl38xx_trigger_device(int asleep, void __iomem *device_base)
 {
-	u32 reg, counter = 0;
+	u32 reg;
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
+	u32 counter = 0;
 	struct timeval current_time;
 	DEBUG(SHOW_FUNCTION_CALLS, "isl38xx trigger device\n");
 #endif
@@ -131,7 +132,6 @@ isl38xx_trigger_device(int asleep, void 
 		      current_time.tv_sec, (long)current_time.tv_usec,
 		      readl(device_base + ISL38XX_CTRL_STAT_REG));
 #endif
-		udelay(ISL38XX_WRITEIO_DELAY);
 
 		reg = readl(device_base + ISL38XX_INT_IDENT_REG);
 		if (reg == 0xabadface) {
@@ -145,7 +145,9 @@ isl38xx_trigger_device(int asleep, void 
 			while (reg = readl(device_base + ISL38XX_CTRL_STAT_REG),
 			       (reg & ISL38XX_CTRL_STAT_SLEEPMODE) == 0) {
 				udelay(ISL38XX_WRITEIO_DELAY);
+#if VERBOSE > SHOW_ERROR_MESSAGES
 				counter++;
+#endif
 			}
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
@@ -153,10 +155,6 @@ isl38xx_trigger_device(int asleep, void 
 			      "%08li.%08li Device register read %08x\n",
 			      current_time.tv_sec, (long)current_time.tv_usec,
 			      readl(device_base + ISL38XX_CTRL_STAT_REG));
-#endif
-			udelay(ISL38XX_WRITEIO_DELAY);
-
-#if VERBOSE > SHOW_ERROR_MESSAGES
 			do_gettimeofday(&current_time);
 			DEBUG(SHOW_TRACING,
 			      "%08li.%08li Device asleep counter %i\n",
@@ -171,7 +169,6 @@ isl38xx_trigger_device(int asleep, void 
 
 		/* perform another read on the Device Status Register */
 		reg = readl(device_base + ISL38XX_CTRL_STAT_REG);
-		udelay(ISL38XX_WRITEIO_DELAY);
 
 #if VERBOSE > SHOW_ERROR_MESSAGES
 		do_gettimeofday(&current_time);
@@ -187,7 +184,6 @@ isl38xx_trigger_device(int asleep, void 
 
 		isl38xx_w32_flush(device_base, ISL38XX_DEV_INT_UPDATE,
 				  ISL38XX_DEV_INT_REG);
-		udelay(ISL38XX_WRITEIO_DELAY);
 	}
 }
 
---
0.99.8.GIT


--- NEW FILE 3009-prism54-Transmit-stats-updated-in-wrong-place.txt ---
Subject: [PATCH] prism54 : Transmit stats updated in wrong place
From: Roger While <simrw at sim-basis.de>
Date: 1131393501 +0100

Move update of the transmit statistics to the correct place.  This
would be just before starting transmission rather than (potentially
long) afterward.

Signed-off-by: Roger While <simrw at sim-basis.de>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/wireless/prism54/islpci_eth.c |   10 +++++-----
 1 files changed, 5 insertions(+), 5 deletions(-)

applies-to: 19bcac799db2f77420ada3ca4356cbb906da17de
0b47939fe616a5e0dd279d98d1eb372e4acc1c09
diff --git a/drivers/net/wireless/prism54/islpci_eth.c b/drivers/net/wireless/prism54/islpci_eth.c
index 3b49efa..56d9783 100644
--- a/drivers/net/wireless/prism54/islpci_eth.c
+++ b/drivers/net/wireless/prism54/islpci_eth.c
@@ -227,17 +227,17 @@ islpci_eth_transmit(struct sk_buff *skb,
 		priv->data_low_tx_full = 1;
 	}
 
+	/* set the transmission time */
+	ndev->trans_start = jiffies;
+	priv->statistics.tx_packets++;
+	priv->statistics.tx_bytes += skb->len;
+
 	/* trigger the device */
 	islpci_trigger(priv);
 
 	/* unlock the driver code */
 	spin_unlock_irqrestore(&priv->slock, flags);
 
-	/* set the transmission time */
-	ndev->trans_start = jiffies;
-	priv->statistics.tx_packets++;
-	priv->statistics.tx_bytes += skb->len;
-
 	return 0;
 
       drop_free:
---
0.99.8.GIT


--- NEW FILE 3010-Fix-sparse-warning-in-e100-driver.txt ---
Subject: [PATCH] Fix sparse warning in e100 driver.
From: Luiz Fernando Capitulino <lcapitulino at mandriva.com.br>
Date: 1131394452 -0200

The patch below fixes the following sparse warnings:

drivers/net/e100.c:1481:13: warning: Using plain integer as NULL pointer
drivers/net/e100.c:1767:27: warning: Using plain integer as NULL pointer
drivers/net/e100.c:1847:27: warning: Using plain integer as NULL pointer

Signed-off-by: Luiz Capitulino <lcapitulino at mandriva.com.br>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/e100.c |    6 +++---
 1 files changed, 3 insertions(+), 3 deletions(-)

applies-to: 0e7d5bceaba4a2ca0d55accdd59218edc4d023c5
097688ef4710648db335c3c4fa243751f60b330a
diff --git a/drivers/net/e100.c b/drivers/net/e100.c
index eb169a8..7a6aeae 100644
--- a/drivers/net/e100.c
+++ b/drivers/net/e100.c
@@ -1478,7 +1478,7 @@ static inline int e100_rx_alloc_skb(stru
 
 	if(pci_dma_mapping_error(rx->dma_addr)) {
 		dev_kfree_skb_any(rx->skb);
-		rx->skb = 0;
+		rx->skb = NULL;
 		rx->dma_addr = 0;
 		return -ENOMEM;
 	}
@@ -1764,7 +1764,7 @@ static int e100_up(struct nic *nic)
 	if((err = e100_hw_init(nic)))
 		goto err_clean_cbs;
 	e100_set_multicast_list(nic->netdev);
-	e100_start_receiver(nic, 0);
+	e100_start_receiver(nic, NULL);
 	mod_timer(&nic->watchdog, jiffies);
 	if((err = request_irq(nic->pdev->irq, e100_intr, SA_SHIRQ,
 		nic->netdev->name, nic->netdev)))
@@ -1844,7 +1844,7 @@ static int e100_loopback_test(struct nic
 		mdio_write(nic->netdev, nic->mii.phy_id, MII_BMCR,
 			BMCR_LOOPBACK);
 
-	e100_start_receiver(nic, 0);
+	e100_start_receiver(nic, NULL);
 
 	if(!(skb = dev_alloc_skb(ETH_DATA_LEN))) {
 		err = -ENOMEM;
---
0.99.8.GIT


--- NEW FILE 3011-atmel-memset-correct-range.txt ---
Subject: [PATCH] atmel: memset correct range
From: Alexey Dobriyan <adobriyan at gmail.com>
Date: 1131399708 +0300

Specify the correct range when calling memset in atmel_get_range.
Do this by specifying the size of the structure, rather than the size
of the pointer.

Signed-off-by: Alexey Dobriyan <adobriyan at gmail.com>
Signed-off-by: John W. Linville <linville at tuxdriver.com>

---

 drivers/net/wireless/atmel.c |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: eb12a04c252ebc9475e6d77bd47de1c4af9a748b
f36be62115aabd50b4eda0f06f07ab5fae2e9cfd
diff --git a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
index 1fbe027..a3e2352 100644
--- a/drivers/net/wireless/atmel.c
+++ b/drivers/net/wireless/atmel.c
@@ -2217,7 +2217,7 @@ static int atmel_get_range(struct net_de
 	int k,i,j;
 
 	dwrq->length = sizeof(struct iw_range);
-	memset(range, 0, sizeof(range));
+	memset(range, 0, sizeof(struct iw_range));
 	range->min_nwid = 0x0000;
 	range->max_nwid = 0x0000;
 	range->num_channels = 0;
---
0.99.8.GIT


--- NEW FILE 3028-PPP-handle-misaligned-accesses.txt ---
Subject: [PATCH] [PPP]: handle misaligned accesses
From: Philippe De Muyter <phdm at macqel.be>
Date: 1131471626 -0800

From: "Philippe De Muyter" <phdm at macqel.be>

This patch avoids ppp-generated kernel crashes on machines where unaligned
accesses are forbidden (ie: m68000), by fixing ppp alignment setting for
reused skb's.

Signed-off-by: Philippe De Muyter <phdm at macqel.be>
Cc: "David S. Miller" <davem at davemloft.net>
Cc: Paul Mackerras <paulus at samba.org>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: David S. Miller <davem at davemloft.net>

---

 drivers/net/ppp_async.c |   17 ++++++++++++++---
 1 files changed, 14 insertions(+), 3 deletions(-)

applies-to: db09e8efee33d1e7d4527d81a3c1b0ece03cea33
6722e78c90054101e6797d5944cdc81af9897a0a
diff --git a/drivers/net/ppp_async.c b/drivers/net/ppp_async.c
index 59e8183..400f652 100644
--- a/drivers/net/ppp_async.c
+++ b/drivers/net/ppp_async.c
@@ -31,6 +31,7 @@
 #include <linux/spinlock.h>
 #include <linux/init.h>
 #include <asm/uaccess.h>
+#include <asm/string.h>
 
 #define PPP_VERSION	"2.4.2"
 
@@ -835,8 +836,11 @@ process_input_packet(struct asyncppp *ap
  err:
 	/* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */
 	ap->state = SC_PREV_ERROR;
-	if (skb)
+	if (skb) {
+		/* make skb appear as freshly allocated */
 		skb_trim(skb, 0);
+		skb_reserve(skb, - skb_headroom(skb));
+	}
 }
 
 /* Called when the tty driver has data for us. Runs parallel with the
@@ -889,10 +893,17 @@ ppp_async_input(struct asyncppp *ap, con
 				skb = dev_alloc_skb(ap->mru + PPP_HDRLEN + 2);
 				if (skb == 0)
 					goto nomem;
-				/* Try to get the payload 4-byte aligned */
+ 				ap->rpkt = skb;
+ 			}
+ 			if (skb->len == 0) {
+ 				/* Try to get the payload 4-byte aligned.
+ 				 * This should match the
+ 				 * PPP_ALLSTATIONS/PPP_UI/compressed tests in
+ 				 * process_input_packet, but we do not have
+ 				 * enough chars here to test buf[1] and buf[2].
+ 				 */
 				if (buf[0] != PPP_ALLSTATIONS)
 					skb_reserve(skb, 2 + (buf[0] & 1));
-				ap->rpkt = skb;
 			}
 			if (n > skb_tailroom(skb)) {
 				/* packet overflowed MRU */
---
0.99.8.GIT


--- NEW FILE 3030-IRDA-donauboe-locking-fix.txt ---
Subject: [PATCH] [IRDA] donauboe: locking fix
From: Andrew Morton <akpm at osdl.org>
Date: 1131471673 -0800

From: Andrew Morton <akpm at osdl.org>

Two missing unlocks, as noted by Ted Unangst <tedu at coverity.com>

Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: David S. Miller <davem at davemloft.net>

---

 drivers/net/irda/donauboe.c |   14 +++++++++-----
 1 files changed, 9 insertions(+), 5 deletions(-)

applies-to: 7ca8e019573362620638e14e32bb519770ee6945
ac7c98eca88a854755475fcfe1b2bf5f97f90d99
diff --git a/drivers/net/irda/donauboe.c b/drivers/net/irda/donauboe.c
index 0282771..3137592 100644
--- a/drivers/net/irda/donauboe.c
+++ b/drivers/net/irda/donauboe.c
@@ -1459,8 +1459,10 @@ toshoboe_net_ioctl (struct net_device *d
        */
       IRDA_DEBUG (1, "%s(BANDWIDTH), %s, (%X/%ld\n", __FUNCTION__
           ,dev->name, INB (OBOE_STATUS), irq->ifr_baudrate );
-      if (!in_interrupt () && !capable (CAP_NET_ADMIN))
-        return -EPERM;
+      if (!in_interrupt () && !capable (CAP_NET_ADMIN)) {
+	ret = -EPERM;
+	goto out;
+      }
 
       /* self->speed=irq->ifr_baudrate; */
       /* toshoboe_setbaud(self); */
@@ -1470,8 +1472,10 @@ toshoboe_net_ioctl (struct net_device *d
     case SIOCSMEDIABUSY:       /* Set media busy */
       IRDA_DEBUG (1, "%s(MEDIABUSY), %s, (%X/%x)\n", __FUNCTION__
           ,dev->name, INB (OBOE_STATUS), capable (CAP_NET_ADMIN) );
-      if (!capable (CAP_NET_ADMIN))
-        return -EPERM;
+      if (!capable (CAP_NET_ADMIN)) {
+	ret = -EPERM;
+	goto out;
+      }
       irda_device_set_media_busy (self->netdev, TRUE);
       break;
     case SIOCGRECEIVING:       /* Check if we are receiving right now */
@@ -1483,7 +1487,7 @@ toshoboe_net_ioctl (struct net_device *d
       IRDA_DEBUG (1, "%s(?), %s, (cmd=0x%X)\n", __FUNCTION__, dev->name, cmd);
       ret = -EOPNOTSUPP;
     }
-
+out:
   spin_unlock_irqrestore(&self->spinlock, flags);
   return ret;
 
---
0.99.8.GIT


--- NEW FILE 3053-SERIAL-IOC3-Update-8250-driver-bits.txt ---
Subject: [PATCH] [SERIAL] IOC3: Update 8250 driver bits
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1131491451 +0000

Update the support for the 16550 present on most IOC3 configurations to use
the current API.

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
Signed-off-by: Russell King <rmk+kernel at arm.linux.org.uk>

---

 drivers/net/ioc3-eth.c |   38 ++++++++++++++++++++------------------
 1 files changed, 20 insertions(+), 18 deletions(-)

applies-to: ecfc614d514bd5b43a98cf4c62fdd2f47d86e33c
15a93807826a5cbffb47d6bfbeeee108d6da1dbc
diff --git a/drivers/net/ioc3-eth.c b/drivers/net/ioc3-eth.c
index 49e5467..6a3129b 100644
--- a/drivers/net/ioc3-eth.c
+++ b/drivers/net/ioc3-eth.c
@@ -46,10 +46,8 @@
 #include <linux/udp.h>
 
 #ifdef CONFIG_SERIAL_8250
-#include <linux/serial.h>
-#include <asm/serial.h>
-#define IOC3_BAUD (22000000 / (3*16))
-#define IOC3_COM_FLAGS (ASYNC_BOOT_AUTOCONF | ASYNC_SKIP_TEST)
+#include <linux/serial_core.h>
+#include <linux/serial_8250.h>
 #endif
 
 #include <linux/netdevice.h>
@@ -1146,12 +1144,11 @@ static inline int ioc3_is_menet(struct p
  * around ioc3 oddities in this respect.
  *
  * The IOC3 serials use a 22MHz clock rate with an additional divider by 3.
- * (IOC3_BAUD = (22000000 / (3*16)))
  */
 
 static void __devinit ioc3_serial_probe(struct pci_dev *pdev, struct ioc3 *ioc3)
 {
-	struct serial_struct req;
+	struct uart_port port;
 
 	/*
 	 * We need to recognice and treat the fourth MENET serial as it
@@ -1165,20 +1162,25 @@ static void __devinit ioc3_serial_probe(
 	if (ioc3_is_menet(pdev) && PCI_SLOT(pdev->devfn) == 3)
 		return;
 
-	/* Register to interrupt zero because we share the interrupt with
-	   the serial driver which we don't properly support yet.  */
-	memset(&req, 0, sizeof(req));
-	req.irq             = 0;
-	req.flags           = IOC3_COM_FLAGS;
-	req.io_type         = SERIAL_IO_MEM;
-	req.iomem_reg_shift = 0;
-	req.baud_base       = IOC3_BAUD;
+	/*
+	 * Register to interrupt zero because we share the interrupt with
+	 * the serial driver which we don't properly support yet.
+	 *
+	 * Can't use UPF_IOREMAP as the whole of IOC3 resources have already
+	 * been registered.
+	 */
+	memset(&port, 0, sizeof(port));
+	port.irq      = 0;
+	port.flags    = UPF_SKIP_TEST | UPF_BOOT_AUTOCONF;
+	port.iotype   = UPIO_MEM;
+	port.regshift = 0;
+	port.uartclk  = 22000000 / 3;
 
-	req.iomem_base      = (unsigned char *) &ioc3->sregs.uarta;
-	register_serial(&req);
+	port.membase  = (unsigned char *) &ioc3->sregs.uarta;
+	serial8250_register_port(&port);
 
-	req.iomem_base      = (unsigned char *) &ioc3->sregs.uartb;
-	register_serial(&req);
+	port.membase  = (unsigned char *) &ioc3->sregs.uartb;
+	serial8250_register_port(&port);
 }
 #endif
 
---
0.99.8.GIT


--- NEW FILE 3055-skge-clear-PCI-PHY-COMA-mode-on-boot.txt ---
Subject: [PATCH] skge: clear PCI PHY COMA mode on boot
From: Stephen Hemminger <shemminger at osdl.org>
Date: 1131474820 -0800

When skge is booted up, the PHY may be stuck in power down state
by the previous OS. So we may need to turn it on.

Signed-off-by: Stephen Hemminger <shemminger at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/skge.c |   10 ++++++++++
 drivers/net/skge.h |    2 ++
 2 files changed, 12 insertions(+), 0 deletions(-)

applies-to: ae8af7e85d0a7c402cca7d31eac2935897e1d698
adba9e23b4066f1d741a2076fc6ad18b6c0cea44
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 572f121..fe806db 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2893,6 +2893,7 @@ static const char *skge_board_name(const
  */
 static int skge_reset(struct skge_hw *hw)
 {
+	u32 reg;
 	u16 ctst;
 	u8 t8, mac_cfg, pmd_type, phy_type;
 	int i;
@@ -2971,6 +2972,7 @@ static int skge_reset(struct skge_hw *hw
 		/* switch power to VCC (WA for VAUX problem) */
 		skge_write8(hw, B0_POWER_CTRL,
 			    PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_OFF | PC_VCC_ON);
+
 		/* avoid boards with stuck Hardware error bits */
 		if ((skge_read32(hw, B0_ISRC) & IS_HW_ERR) &&
 		    (skge_read32(hw, B0_HWE_ISRC) & IS_IRQ_SENSOR)) {
@@ -2978,6 +2980,14 @@ static int skge_reset(struct skge_hw *hw
 			hw->intr_mask &= ~IS_HW_ERR;
 		}
 
+		/* Clear PHY COMA */
+		skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_ON);
+		pci_read_config_dword(hw->pdev, PCI_DEV_REG1, &reg);
+		reg &= ~PCI_PHY_COMA;
+		pci_write_config_dword(hw->pdev, PCI_DEV_REG1, reg);
+		skge_write8(hw, B2_TST_CTRL1, TST_CFG_WRITE_OFF);
+
+
 		for (i = 0; i < hw->ports; i++) {
 			skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_SET);
 			skge_write16(hw, SK_REG(i, GMAC_LINK_CTRL), GMLC_RST_CLR);
diff --git a/drivers/net/skge.h b/drivers/net/skge.h
index 72c175b..ee123c1 100644
--- a/drivers/net/skge.h
+++ b/drivers/net/skge.h
@@ -6,6 +6,8 @@
 
 /* PCI config registers */
 #define PCI_DEV_REG1	0x40
+#define  PCI_PHY_COMA	0x8000000
+#define  PCI_VIO	0x2000000
 #define PCI_DEV_REG2	0x44
 #define  PCI_REV_DESC	 0x4
 
---
0.99.8.GIT


--- NEW FILE 3056-skge-use-kzalloc.txt ---
Subject: [PATCH] skge: use kzalloc
From: Stephen Hemminger <shemminger at osdl.org>
Date: 1131474821 -0800

Can use kzalloc in skge driver.

Signed-off-by: Stephen Hemminger <shemminger at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/skge.c |    3 +--
 1 files changed, 1 insertions(+), 2 deletions(-)

applies-to: ca77fccedcc52d4b5850b2823a4e4ad5e840ddd1
7e86306113ca9e418e49ff1c7c0984f8ffe8cf61
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index fe806db..f411c5c 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -3168,14 +3168,13 @@ static int __devinit skge_probe(struct p
 #endif
 
 	err = -ENOMEM;
-	hw = kmalloc(sizeof(*hw), GFP_KERNEL);
+	hw = kzalloc(sizeof(*hw), GFP_KERNEL);
 	if (!hw) {
 		printk(KERN_ERR PFX "%s: cannot allocate hardware struct\n",
 		       pci_name(pdev));
 		goto err_out_free_regions;
 	}
 
-	memset(hw, 0, sizeof(*hw));
 	hw->pdev = pdev;
 	spin_lock_init(&hw->phy_lock);
 	tasklet_init(&hw->ext_tasklet, skge_extirq, (unsigned long) hw);
---
0.99.8.GIT


--- NEW FILE 3057-skge-add-mii-ioctl-support.txt ---
Subject: [PATCH] skge: add mii ioctl support
From: Stephen Hemminger <shemminger at osdl.org>
Date: 1131474822 -0800

Basic MII ioctl support for skge driver.

Signed-off-by: Stephen Hemminger <shemminger at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/skge.c |  172 ++++++++++++++++++++++++++++++++++------------------
 1 files changed, 114 insertions(+), 58 deletions(-)

applies-to: b8ea5564e4bf9c3b4ad69b8b02b6513b684f1166
2cd8e5d36584653c62a6fdf0e7d9fbde5022b5d6
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index f411c5c..a1cfead 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -37,6 +37,7 @@
 #include <linux/delay.h>
 #include <linux/crc32.h>
 #include <linux/dma-mapping.h>
+#include <linux/mii.h>
 #include <asm/irq.h>
 
 #include "skge.h"
@@ -88,8 +89,8 @@ MODULE_DEVICE_TABLE(pci, skge_id_table);
 static int skge_up(struct net_device *dev);
 static int skge_down(struct net_device *dev);
 static void skge_tx_clean(struct skge_port *skge);
-static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
-static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
+static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val);
 static void genesis_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_get_stats(struct skge_port *skge, u64 *data);
 static void yukon_init(struct skge_hw *hw, int port);
@@ -883,32 +884,37 @@ static void skge_link_down(struct skge_p
 		printk(KERN_INFO PFX "%s: Link is down.\n", skge->netdev->name);
 }
 
-static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
+static int __xm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
 {
 	int i;
-	u16 v;
 
 	xm_write16(hw, port, XM_PHY_ADDR, reg | hw->phy_addr);
-	v = xm_read16(hw, port, XM_PHY_DATA);
+	xm_read16(hw, port, XM_PHY_DATA);
 
 	/* Need to wait for external PHY */
 	for (i = 0; i < PHY_RETRIES; i++) {
 		udelay(1);
-		if (xm_read16(hw, port, XM_MMU_CMD)
-		    & XM_MMU_PHY_RDY)
+		if (xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_RDY)
 			goto ready;
 	}
 
-	printk(KERN_WARNING PFX "%s: phy read timed out\n",
-	       hw->dev[port]->name);
-	return 0;
+	return -ETIMEDOUT;
  ready:
-	v = xm_read16(hw, port, XM_PHY_DATA);
+	*val = xm_read16(hw, port, XM_PHY_DATA);
 
+	return 0;
+}
+
+static u16 xm_phy_read(struct skge_hw *hw, int port, u16 reg)
+{
+	u16 v = 0;
+	if (__xm_phy_read(hw, port, reg, &v))
+		printk(KERN_WARNING PFX "%s: phy read timed out\n",
+		       hw->dev[port]->name);
 	return v;
 }
 
-static void xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+static int xm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
 {
 	int i;
 
@@ -918,19 +924,11 @@ static void xm_phy_write(struct skge_hw 
 			goto ready;
 		udelay(1);
 	}
-	printk(KERN_WARNING PFX "%s: phy write failed to come ready\n",
-	       hw->dev[port]->name);
-
+	return -EIO;
 
  ready:
 	xm_write16(hw, port, XM_PHY_DATA, val);
-	for (i = 0; i < PHY_RETRIES; i++) {
-		udelay(1);
-		if (!(xm_read16(hw, port, XM_MMU_CMD) & XM_MMU_PHY_BUSY))
-			return;
-	}
-	printk(KERN_WARNING PFX "%s: phy write timed out\n",
-		       hw->dev[port]->name);
+	return 0;
 }
 
 static void genesis_init(struct skge_hw *hw)
@@ -1400,42 +1398,6 @@ static void genesis_mac_intr(struct skge
 	}
 }
 
-static void gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
-{
-	int i;
-
-	gma_write16(hw, port, GM_SMI_DATA, val);
-	gma_write16(hw, port, GM_SMI_CTRL,
-			 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
-	for (i = 0; i < PHY_RETRIES; i++) {
-		udelay(1);
-
-		if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
-			break;
-	}
-}
-
-static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
-{
-	int i;
-
-	gma_write16(hw, port, GM_SMI_CTRL,
-			 GM_SMI_CT_PHY_AD(hw->phy_addr)
-			 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
-
-	for (i = 0; i < PHY_RETRIES; i++) {
-		udelay(1);
-		if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
-			goto ready;
-	}
-
-	printk(KERN_WARNING PFX "%s: phy read timeout\n",
-	       hw->dev[port]->name);
-	return 0;
- ready:
-	return gma_read16(hw, port, GM_SMI_DATA);
-}
-
 static void genesis_link_up(struct skge_port *skge)
 {
 	struct skge_hw *hw = skge->hw;
@@ -1549,6 +1511,54 @@ static inline void bcom_phy_intr(struct 
 
 }
 
+static int gm_phy_write(struct skge_hw *hw, int port, u16 reg, u16 val)
+{
+	int i;
+
+	gma_write16(hw, port, GM_SMI_DATA, val);
+	gma_write16(hw, port, GM_SMI_CTRL,
+			 GM_SMI_CT_PHY_AD(hw->phy_addr) | GM_SMI_CT_REG_AD(reg));
+	for (i = 0; i < PHY_RETRIES; i++) {
+		udelay(1);
+
+		if (!(gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_BUSY))
+			return 0;
+	}
+
+	printk(KERN_WARNING PFX "%s: phy write timeout\n",
+	       hw->dev[port]->name);
+	return -EIO;
+}
+
+static int __gm_phy_read(struct skge_hw *hw, int port, u16 reg, u16 *val)
+{
+	int i;
+
+	gma_write16(hw, port, GM_SMI_CTRL,
+			 GM_SMI_CT_PHY_AD(hw->phy_addr)
+			 | GM_SMI_CT_REG_AD(reg) | GM_SMI_CT_OP_RD);
+
+	for (i = 0; i < PHY_RETRIES; i++) {
+		udelay(1);
+		if (gma_read16(hw, port, GM_SMI_CTRL) & GM_SMI_CT_RD_VAL)
+			goto ready;
+	}
+
+	return -ETIMEDOUT;
+ ready:
+	*val = gma_read16(hw, port, GM_SMI_DATA);
+	return 0;
+}
+
+static u16 gm_phy_read(struct skge_hw *hw, int port, u16 reg)
+{
+	u16 v = 0;
+	if (__gm_phy_read(hw, port, reg, &v))
+		printk(KERN_WARNING PFX "%s: phy read timeout\n",
+	       hw->dev[port]->name);
+	return v;
+}
+
 /* Marvell Phy Initailization */
 static void yukon_init(struct skge_hw *hw, int port)
 {
@@ -1997,6 +2007,51 @@ static void yukon_phy_intr(struct skge_p
 	/* XXX restart autonegotiation? */
 }
 
+/* Basic MII support */
+static int skge_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+{
+	struct mii_ioctl_data *data = if_mii(ifr);
+	struct skge_port *skge = netdev_priv(dev);
+	struct skge_hw *hw = skge->hw;
+	int err = -EOPNOTSUPP;
+
+	if (!netif_running(dev))
+		return -ENODEV;	/* Phy still in reset */
+
+	switch(cmd) {
+	case SIOCGMIIPHY:
+		data->phy_id = hw->phy_addr;
+
+		/* fallthru */
+	case SIOCGMIIREG: {
+		u16 val = 0;
+		spin_lock_bh(&hw->phy_lock);
+		if (hw->chip_id == CHIP_ID_GENESIS)
+			err = __xm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
+		else
+			err = __gm_phy_read(hw, skge->port, data->reg_num & 0x1f, &val);
+		spin_unlock_bh(&hw->phy_lock);
+		data->val_out = val;
+		break;
+	}
+
+	case SIOCSMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		spin_lock_bh(&hw->phy_lock);
+		if (hw->chip_id == CHIP_ID_GENESIS)
+			err = xm_phy_write(hw, skge->port, data->reg_num & 0x1f,
+				   data->val_in);
+		else
+			err = gm_phy_write(hw, skge->port, data->reg_num & 0x1f,
+				   data->val_in);
+		spin_unlock_bh(&hw->phy_lock);
+		break;
+	}
+	return err;
+}
+
 static void skge_ramset(struct skge_hw *hw, u16 q, u32 start, size_t len)
 {
 	u32 end;
@@ -3058,6 +3113,7 @@ static struct net_device *skge_devinit(s
 	SET_NETDEV_DEV(dev, &hw->pdev->dev);
 	dev->open = skge_up;
 	dev->stop = skge_down;
+	dev->do_ioctl = skge_ioctl;
 	dev->hard_start_xmit = skge_xmit_frame;
 	dev->get_stats = skge_get_stats;
 	if (hw->chip_id == CHIP_ID_GENESIS)
---
0.99.8.GIT


--- NEW FILE 3058-skge-goto-low-power-mode-on-shutdown.txt ---
Subject: [PATCH] skge: goto low power mode on shutdown
From: Stephen Hemminger <shemminger at osdl.org>
Date: 1131474823 -0800

Go into power down mode on shutdown.

Signed-off-by: Stephen Hemminger <shemminger at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/skge.c |   28 ++++++++++++++++++++--------
 1 files changed, 20 insertions(+), 8 deletions(-)

applies-to: 6c3298644228adf71d26a34e8f0028d47c38973b
355ec57243574c439a4b731fc83af6165ec2f1ec
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index a1cfead..ea68d4d 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -1804,6 +1804,25 @@ static void yukon_mac_init(struct skge_h
 	skge_write16(hw, SK_REG(port, TX_GMF_CTRL_T), GMF_OPER_ON);
 }
 
+/* Go into power down mode */
+static void yukon_suspend(struct skge_hw *hw, int port)
+{
+	u16 ctrl;
+
+	ctrl = gm_phy_read(hw, port, PHY_MARV_PHY_CTRL);
+	ctrl |= PHY_M_PC_POL_R_DIS;
+	gm_phy_write(hw, port, PHY_MARV_PHY_CTRL, ctrl);
+
+	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+	ctrl |= PHY_CT_RESET;
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+
+	/* switch IEEE compatible power down mode on */
+	ctrl = gm_phy_read(hw, port, PHY_MARV_CTRL);
+	ctrl |= PHY_CT_PDOWN;
+	gm_phy_write(hw, port, PHY_MARV_CTRL, ctrl);
+}
+
 static void yukon_stop(struct skge_port *skge)
 {
 	struct skge_hw *hw = skge->hw;
@@ -1817,14 +1836,7 @@ static void yukon_stop(struct skge_port 
 			 & ~(GM_GPCR_TX_ENA|GM_GPCR_RX_ENA));
 	gma_read16(hw, port, GM_GP_CTRL);
 
-	if (hw->chip_id == CHIP_ID_YUKON_LITE &&
-	    hw->chip_rev >= CHIP_REV_YU_LITE_A3) {
-		u32 io = skge_read32(hw, B2_GP_IO);
-
-		io |= GP_DIR_9 | GP_IO_9;
-		skge_write32(hw, B2_GP_IO, io);
-		skge_read32(hw, B2_GP_IO);
-	}
+	yukon_suspend(hw, port);
 
 	/* set GPHY Control reset */
 	skge_write8(hw, SK_REG(port, GPHY_CTRL), GPC_RST_SET);
---
0.99.8.GIT


--- NEW FILE 3059-skge-use-prefetch-on-receive.txt ---
Subject: [PATCH] skge: use prefetch on receive
From: Stephen Hemminger <shemminger at osdl.org>
Date: 1131474824 -0800

Use prefetch() in the interrupt path to try and look ahead
at the next place will be looking at in the ring.

Signed-off-by: Stephen Hemminger <shemminger at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/skge.c |   22 +++++++++++++++-------
 1 files changed, 15 insertions(+), 7 deletions(-)

applies-to: de1325d38869a1c77bc9e18e8b608342053dff09
1631aef15193ef8a199982fa3d45db4d07786d7f
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index ea68d4d..389d0be 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -2627,7 +2627,7 @@ static int skge_poll(struct net_device *
 	unsigned int to_do = min(dev->quota, *budget);
 	unsigned int work_done = 0;
 
-	for (e = ring->to_clean; work_done < to_do; e = e->next) {
+	for (e = ring->to_clean; prefetch(e->next), work_done < to_do; e = e->next) {
 		struct skge_rx_desc *rd = e->desc;
 		struct sk_buff *skb;
 		u32 control;
@@ -2660,11 +2660,11 @@ static int skge_poll(struct net_device *
 	if (work_done >=  to_do)
 		return 1; /* not done */
 
-	local_irq_disable();
-	__netif_rx_complete(dev);
+	netif_rx_complete(dev);
 	hw->intr_mask |= portirqmask[skge->port];
 	skge_write32(hw, B0_IMSK, hw->intr_mask);
-	local_irq_enable();
+	skge_read32(hw, B0_IMSK);
+
 	return 0;
 }
 
@@ -2676,7 +2676,7 @@ static inline void skge_tx_intr(struct n
 	struct skge_element *e;
 
 	spin_lock(&skge->tx_lock);
-	for (e = ring->to_clean; e != ring->to_use; e = e->next) {
+	for (e = ring->to_clean; prefetch(e->next), e != ring->to_use; e = e->next) {
 		struct skge_tx_desc *td = e->desc;
 		u32 control;
 
@@ -2829,6 +2829,14 @@ static void skge_extirq(unsigned long da
 	local_irq_enable();
 }
 
+static inline void skge_wakeup(struct net_device *dev)
+{
+	struct skge_port *skge = netdev_priv(dev);
+
+	prefetch(skge->rx_ring.to_clean);
+	netif_rx_schedule(dev);
+}
+
 static irqreturn_t skge_intr(int irq, void *dev_id, struct pt_regs *regs)
 {
 	struct skge_hw *hw = dev_id;
@@ -2840,12 +2848,12 @@ static irqreturn_t skge_intr(int irq, vo
 	status &= hw->intr_mask;
 	if (status & IS_R1_F) {
 		hw->intr_mask &= ~IS_R1_F;
-		netif_rx_schedule(hw->dev[0]);
+		skge_wakeup(hw->dev[0]);
 	}
 
 	if (status & IS_R2_F) {
 		hw->intr_mask &= ~IS_R2_F;
-		netif_rx_schedule(hw->dev[1]);
+		skge_wakeup(hw->dev[1]);
 	}
 
 	if (status & IS_XA1_F)
---
0.99.8.GIT


--- NEW FILE 3060-skge-spelling-fixes.txt ---
Subject: [PATCH] skge: spelling fixes
From: Stephen Hemminger <shemminger at osdl.org>
Date: 1131474825 -0800

Fix some of my bad spelling.

Signed-off-by: Stephen Hemminger <shemminger at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/skge.c |   28 ++++++++++++++--------------
 1 files changed, 14 insertions(+), 14 deletions(-)

applies-to: 7f000cf60191805de8faa54fbf51f02c30abf0c3
8f3f8193a49e1eb0d2e01309fdef2ad4fb33293c
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index 389d0be..df30274 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -130,7 +130,7 @@ static void skge_get_regs(struct net_dev
 		      regs->len - B3_RI_WTO_R1);
 }
 
-/* Wake on Lan only supported on Yukon chps with rev 1 or above */
+/* Wake on Lan only supported on Yukon chips with rev 1 or above */
 static int wol_supported(const struct skge_hw *hw)
 {
 	return !((hw->chip_id == CHIP_ID_GENESIS ||
@@ -170,8 +170,8 @@ static int skge_set_wol(struct net_devic
 	return 0;
 }
 
-/* Determine supported/adverised modes based on hardware.
- * Note: ethtoool ADVERTISED_xxx == SUPPORTED_xxx
+/* Determine supported/advertised modes based on hardware.
+ * Note: ethtool ADVERTISED_xxx == SUPPORTED_xxx
  */
 static u32 skge_supported_modes(const struct skge_hw *hw)
 {
@@ -532,13 +532,13 @@ static inline u32 hwkhz(const struct skg
 		return 78215; /* or:  78.125 MHz */
 }
 
-/* Chip hz to microseconds */
+/* Chip HZ to microseconds */
 static inline u32 skge_clk2usec(const struct skge_hw *hw, u32 ticks)
 {
 	return (ticks * 1000) / hwkhz(hw);
 }
 
-/* Microseconds to chip hz */
+/* Microseconds to chip HZ */
 static inline u32 skge_usecs2clk(const struct skge_hw *hw, u32 usec)
 {
 	return hwkhz(hw) * usec / 1000;
@@ -1163,7 +1163,7 @@ static void bcom_phy_init(struct skge_po
 	xm_phy_write(hw, port, PHY_BCOM_P_EXT_CTRL, ext);
 	xm_phy_write(hw, port, PHY_BCOM_CTRL, ctl);
 
-	/* Use link status change interrrupt */
+	/* Use link status change interrupt */
 	xm_phy_write(hw, port, PHY_BCOM_INT_MASK, PHY_B_DEF_MSK);
 
 	bcom_check_link(hw, port);
@@ -1203,7 +1203,7 @@ static void genesis_mac_init(struct skge
 	skge_write32(hw, B2_GP_IO, r);
 	skge_read32(hw, B2_GP_IO);
 
-	/* Enable GMII interfac */
+	/* Enable GMII interface */
 	xm_write16(hw, port, XM_HW_CFG, XM_HW_GMII_MD);
 
 	bcom_phy_init(skge, jumbo);
@@ -1254,7 +1254,7 @@ static void genesis_mac_init(struct skge
 	 * that jumbo frames larger than 8192 bytes will be
 	 * truncated. Disabling all bad frame filtering causes
 	 * the RX FIFO to operate in streaming mode, in which
-	 * case the XMAC will start transfering frames out of the
+	 * case the XMAC will start transferring frames out of the
 	 * RX FIFO as soon as the FIFO threshold is reached.
 	 */
 	xm_write32(hw, port, XM_MODE, XM_DEF_MODE);
@@ -1321,7 +1321,7 @@ static void genesis_stop(struct skge_por
 		     port == 0 ? PA_CLR_TO_TX1 : PA_CLR_TO_TX2);
 
 	/*
-	 * If the transfer stucks at the MAC the STOP command will not
+	 * If the transfer sticks at the MAC the STOP command will not
 	 * terminate if we don't flush the XMAC's transmit FIFO !
 	 */
 	xm_write32(hw, port, XM_MODE,
@@ -1559,7 +1559,7 @@ static u16 gm_phy_read(struct skge_hw *h
 	return v;
 }
 
-/* Marvell Phy Initailization */
+/* Marvell Phy Initialization */
 static void yukon_init(struct skge_hw *hw, int port)
 {
 	struct skge_port *skge = netdev_priv(hw->dev[port]);
@@ -2156,7 +2156,7 @@ static int skge_up(struct net_device *de
 	hw->intr_mask |= portirqmask[port];
 	skge_write32(hw, B0_IMSK, hw->intr_mask);
 
-	/* Initialze MAC */
+	/* Initialize MAC */
 	spin_lock_bh(&hw->phy_lock);
 	if (hw->chip_id == CHIP_ID_GENESIS)
 		genesis_mac_init(hw, port);
@@ -2476,7 +2476,7 @@ static void yukon_set_multicast(struct n
 	reg = gma_read16(hw, port, GM_RX_CTRL);
 	reg |= GM_RXCR_UCF_ENA;
 
-	if (dev->flags & IFF_PROMISC) 		/* promiscious */
+	if (dev->flags & IFF_PROMISC) 		/* promiscuous */
 		reg &= ~(GM_RXCR_UCF_ENA | GM_RXCR_MCF_ENA);
 	else if (dev->flags & IFF_ALLMULTI)	/* all multicast */
 		memset(filter, 0xff, sizeof(filter));
@@ -2799,7 +2799,7 @@ static void skge_error_irq(struct skge_h
 }
 
 /*
- * Interrrupt from PHY are handled in tasklet (soft irq)
+ * Interrupt from PHY are handled in tasklet (soft irq)
  * because accessing phy registers requires spin wait which might
  * cause excess interrupt latency.
  */
@@ -3233,7 +3233,7 @@ static int __devinit skge_probe(struct p
 	}
 
 #ifdef __BIG_ENDIAN
-	/* byte swap decriptors in hardware */
+	/* byte swap descriptors in hardware */
 	{
 		u32 reg;
 
---
0.99.8.GIT


--- NEW FILE 3061-skge-increase-version-number.txt ---
Subject: [PATCH] skge: increase version number
From: Stephen Hemminger <shemminger at osdl.org>
Date: 1131474826 -0800

Increase the driver version number and print version when
probing.

Signed-off-by: Stephen Hemminger <shemminger at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/skge.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

applies-to: 147067f2b6973643483472c3c09eb05ee0973fbf
d7eaee087a8cb850ed33ee39a3e2a0f02ecff44c
diff --git a/drivers/net/skge.c b/drivers/net/skge.c
index df30274..596c93b 100644
--- a/drivers/net/skge.c
+++ b/drivers/net/skge.c
@@ -43,7 +43,7 @@
 #include "skge.h"
 
 #define DRV_NAME		"skge"
-#define DRV_VERSION		"1.1"
+#define DRV_VERSION		"1.2"
 #define PFX			DRV_NAME " "
 
 #define DEFAULT_TX_RING_SIZE	128
@@ -3273,7 +3273,7 @@ static int __devinit skge_probe(struct p
 	if (err)
 		goto err_out_free_irq;
 
-	printk(KERN_INFO PFX "addr 0x%lx irq %d chip %s rev %d\n",
+	printk(KERN_INFO PFX DRV_VERSION " addr 0x%lx irq %d chip %s rev %d\n",
 	       pci_resource_start(pdev, 0), pdev->irq,
 	       skge_board_name(hw), hw->chip_rev);
 
---
0.99.8.GIT


--- NEW FILE 3062-wireless-ipw2100-kill-unused-var-warnings-for-debug-disabled-code.txt ---
Subject: [PATCH] [wireless ipw2100] kill unused-var warnings for debug-disabled code
From: Jeff Garzik <jgarzik at pobox.com>
Date: 1131515378 -0500

---

 drivers/net/wireless/ipw2100.c |    4 ++++
 1 files changed, 4 insertions(+), 0 deletions(-)

applies-to: 11f4ab9bcc75210c2b4a15dc33c3f4d6a612deec
c2a8fad43376b2567087358a9cc46844f742342e
diff --git a/drivers/net/wireless/ipw2100.c b/drivers/net/wireless/ipw2100.c
index 877ac51..a2e6214 100644
--- a/drivers/net/wireless/ipw2100.c
+++ b/drivers/net/wireless/ipw2100.c
@@ -3748,6 +3748,8 @@ static ssize_t store_memory(struct devic
 	struct net_device *dev = priv->net_dev;
 	const char *p = buf;
 
+	(void) dev; /* kill unused-var warning for debug-only code */
+
 	if (count < 1)
 		return count;
 
@@ -4066,6 +4068,8 @@ static ssize_t store_scan_age(struct dev
 	unsigned long val;
 	char *p = buffer;
 
+	(void) dev; /* kill unused-var warning for debug-only code */
+
 	IPW_DEBUG_INFO("enter\n");
 
 	strncpy(buffer, buf, len);
---
0.99.8.GIT


--- NEW FILE 3064-b44-replace-B44_FLAG_INIT_COMPLETE-with-netif_running.txt ---
Subject: [PATCH] b44: replace B44_FLAG_INIT_COMPLETE with netif_running()
From: Francois Romieu <romieu at fr.zoreil.com>
Date: 1131489380 +0100

Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |    6 ++----
 drivers/net/b44.h |    1 -
 2 files changed, 2 insertions(+), 5 deletions(-)

applies-to: 9c5d3b5b630f3a4db26b4193bb4e1da051b7ed3a
b9dcbb40f40d60c7e33a2b7ea858fcd27c35cc00
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index ecc2e32..f1675dc 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -1392,7 +1392,6 @@ static int b44_open(struct net_device *d
 
 	b44_init_rings(bp);
 	b44_init_hw(bp);
-	bp->flags |= B44_FLAG_INIT_COMPLETE;
 
 	netif_carrier_off(dev);
 	b44_check_phy(bp);
@@ -1456,7 +1455,6 @@ static int b44_close(struct net_device *
 #endif
 	b44_halt(bp);
 	b44_free_rings(bp);
-	bp->flags &= ~B44_FLAG_INIT_COMPLETE;
 	netif_carrier_off(bp->dev);
 
 	spin_unlock_irq(&bp->lock);
@@ -1608,7 +1606,7 @@ static int b44_get_settings(struct net_d
 {
 	struct b44 *bp = netdev_priv(dev);
 
-	if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
+	if (!netif_running(dev))
 		return -EAGAIN;
 	cmd->supported = (SUPPORTED_Autoneg);
 	cmd->supported |= (SUPPORTED_100baseT_Half |
@@ -1646,7 +1644,7 @@ static int b44_set_settings(struct net_d
 {
 	struct b44 *bp = netdev_priv(dev);
 
-	if (!(bp->flags & B44_FLAG_INIT_COMPLETE))
+	if (!netif_running(dev))
 		return -EAGAIN;
 
 	/* We do not support gigabit. */
diff --git a/drivers/net/b44.h b/drivers/net/b44.h
index 7afeaf6..b178662 100644
--- a/drivers/net/b44.h
+++ b/drivers/net/b44.h
@@ -420,7 +420,6 @@ struct b44 {
 
 	u32			dma_offset;
 	u32			flags;
-#define B44_FLAG_INIT_COMPLETE	0x00000001
 #define B44_FLAG_BUGGY_TXPTR	0x00000002
 #define B44_FLAG_REORDER_BUG	0x00000004
 #define B44_FLAG_PAUSE_AUTO	0x00008000
---
0.99.8.GIT


--- NEW FILE 3065-b44-race-on-device-closing.txt ---
Subject: [PATCH] b44: race on device closing
From: Francois Romieu <romieu at fr.zoreil.com>
Date: 1131489432 +0100

Usual fix:
- b44_interrupt() does not schedule NAPI polling when the device is
  going down;
- b44_close() waits for any scheduled NAPI polling before it starts
  to release the private structures of the device.

Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |   11 +++++++++++
 1 files changed, 11 insertions(+), 0 deletions(-)

applies-to: e044be0f5fe46fee4990f819fd30a7dc89e3694a
ba5eec9c55ec4be99d21a6ea614003b65d7f37d7
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index f1675dc..e829bee 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -909,6 +909,12 @@ static irqreturn_t b44_interrupt(int irq
 	istat &= imask;
 	if (istat) {
 		handled = 1;
+
+		if (unlikely(!netif_running(dev))) {
+			printk(KERN_INFO "%s: late interrupt.\n", dev->name);
+			goto irq_ack;
+		}
+
 		if (netif_rx_schedule_prep(dev)) {
 			/* NOTE: These writes are posted by the readback of
 			 *       the ISTAT register below.
@@ -921,6 +927,7 @@ static irqreturn_t b44_interrupt(int irq
 			       dev->name);
 		}
 
+irq_ack:
 		bw32(bp, B44_ISTAT, istat);
 		br32(bp, B44_ISTAT);
 	}
@@ -1446,6 +1453,8 @@ static int b44_close(struct net_device *
 
 	netif_stop_queue(dev);
 
+	netif_poll_disable(dev);
+
 	del_timer_sync(&bp->timer);
 
 	spin_lock_irq(&bp->lock);
@@ -1461,6 +1470,8 @@ static int b44_close(struct net_device *
 
 	free_irq(dev->irq, dev);
 
+	netif_poll_enable(dev);
+
 	b44_free_consistent(bp);
 
 	return 0;
---
0.99.8.GIT


--- NEW FILE 3066-b44-increase-version-number.txt ---
Subject: [PATCH] b44: increase version number
From: Francois Romieu <romieu at fr.zoreil.com>
Date: 1131489481 +0100

Signed-off-by: Francois Romieu <romieu at fr.zoreil.com>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/b44.c |    4 ++--
 1 files changed, 2 insertions(+), 2 deletions(-)

applies-to: 79070a6366a44bf37101f0dfa3ee73bbc1192120
eac1dfcb32fbe8b0d9135caea90b0bba9945360f
diff --git a/drivers/net/b44.c b/drivers/net/b44.c
index e829bee..b38fa24 100644
--- a/drivers/net/b44.c
+++ b/drivers/net/b44.c
@@ -29,8 +29,8 @@
 
 #define DRV_MODULE_NAME		"b44"
 #define PFX DRV_MODULE_NAME	": "
-#define DRV_MODULE_VERSION	"0.95"
-#define DRV_MODULE_RELDATE	"Aug 3, 2004"
+#define DRV_MODULE_VERSION	"0.96"
+#define DRV_MODULE_RELDATE	"Nov 8, 2005"
 
 #define B44_DEF_MSG_ENABLE	  \
 	(NETIF_MSG_DRV		| \
---
0.99.8.GIT


***** Error reading new file: [Errno 2] No such file or directory: '3067-cris-v10-eth-use-ethtool_ops.txt'

--- NEW FILE 3069-uml_net-use-ethtool_ops.txt ---
Subject: [PATCH] uml_net: use ethtool_ops
From: Christoph Hellwig <hch at lst.de>
Date: 1131340881 +0100

Signed-off-by: Christoph Hellwig <hch at lst.de>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 arch/um/drivers/net_kern.c |   36 ++++++++++--------------------------
 1 files changed, 10 insertions(+), 26 deletions(-)

applies-to: 3e7169491a3f04cac8cf6ae25a6c695d6c31ee17
6d3874844f3279f170dca5339b8a94d6f1868425
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index fe865d9..4cf31a2 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -243,34 +243,18 @@ static int uml_net_change_mtu(struct net
 	return err;
 }
 
-static int uml_net_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
+static void uml_net_get_drvinfo(struct net_device *dev,
+				struct ethtool_drvinfo *info)
 {
-	static const struct ethtool_drvinfo info = {
-		.cmd     = ETHTOOL_GDRVINFO,
-		.driver  = DRIVER_NAME,
-		.version = "42",
-	};
-	void *useraddr;
-	u32 ethcmd;
-
-	switch (cmd) {
-	case SIOCETHTOOL:
-		useraddr = ifr->ifr_data;
-		if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
-			return -EFAULT;
-		switch (ethcmd) {
-		case ETHTOOL_GDRVINFO:
-			if (copy_to_user(useraddr, &info, sizeof(info)))
-				return -EFAULT;
-			return 0;
-		default:
-			return -EOPNOTSUPP;
-		}
-	default:
-		return -EINVAL;
-	}
+	strcpy(info->driver, DRIVER_NAME);
+	strcpy(info->version, "42");
 }
 
+static struct ethtool_ops uml_net_ethtool_ops = {
+	.get_drvinfo	= uml_net_get_drvinfo,
+	.get_link	= ethtool_op_get_link,
+};
+
 void uml_net_user_timer_expire(unsigned long _conn)
 {
 #ifdef undef
@@ -359,7 +343,7 @@ static int eth_configure(int n, void *in
 	dev->tx_timeout = uml_net_tx_timeout;
 	dev->set_mac_address = uml_net_set_mac;
 	dev->change_mtu = uml_net_change_mtu;
-	dev->do_ioctl = uml_net_ioctl;
+	dev->ethtool_ops = &uml_net_ethtool_ops;
 	dev->watchdog_timeo = (HZ >> 1);
 	dev->irq = UM_ETH_IRQ;
 
---
0.99.8.GIT


--- NEW FILE 3072-dgrs-fix-warnings-when-CONFIG_ISA-and-CONFIG_PCI-are-not-enabled.txt ---
Subject: [PATCH] dgrs: fix warnings when CONFIG_ISA and CONFIG_PCI are not enabled
From: Ashutosh Naik <ashutosh.naik at gmail.com>
Date: 1131349402 -0800

This patch fixes compiler warnings when CONFIG_ISA and CONFIG_PCI are not
enabled in the dgrc network driver.

Signed-off-by: Ashutosh Naik <ashutosh.naik at gmail.com>
Cc: Jeff Garzik <jgarzik at pobox.com>
Signed-off-by: Andrew Morton <akpm at osdl.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/dgrs.c |   16 +++++++---------
 1 files changed, 7 insertions(+), 9 deletions(-)

applies-to: 3f2b3148c71b9ffb2752af9a4780316441db574b
385023cb8972971540d17c92baf0132693955f5f
diff --git a/drivers/net/dgrs.c b/drivers/net/dgrs.c
index 7809838..2a290cc 100644
--- a/drivers/net/dgrs.c
+++ b/drivers/net/dgrs.c
@@ -1549,7 +1549,7 @@ MODULE_PARM_DESC(nicmode, "Digi RightSwi
 static int __init dgrs_init_module (void)
 {
 	int	i;
-	int eisacount = 0, pcicount = 0;
+	int	cardcount = 0;
 
 	/*
 	 *	Command line variable overrides
@@ -1591,15 +1591,13 @@ static int __init dgrs_init_module (void
 	 *	Find and configure all the cards
 	 */
 #ifdef CONFIG_EISA
-	eisacount = eisa_driver_register(&dgrs_eisa_driver);
-	if (eisacount < 0)
-		return eisacount;
-#endif
-#ifdef CONFIG_PCI
-	pcicount = pci_register_driver(&dgrs_pci_driver);
-	if (pcicount)
-		return pcicount;
+	cardcount = eisa_driver_register(&dgrs_eisa_driver);
+	if (cardcount < 0)
+		return cardcount;
 #endif
+	cardcount = pci_register_driver(&dgrs_pci_driver);
+	if (cardcount)
+		return cardcount;
 	return 0;
 }
 
---
0.99.8.GIT


--- NEW FILE 3073-IOC-And-don-t-mark-the-things-as-broken-Cowboy.txt ---
Subject: [PATCH] IOC: And don't mark the things as broken Cowboy.
From: Ralf Baechle <ralf at linux-mips.org>
Date: 1131477024 +0000

And don't mark the things as broken Cowboy.

Signed-off-by: Ralf Baechle <ralf at linux-mips.org>
Signed-off-by: Jeff Garzik <jgarzik at pobox.com>

---

 drivers/net/Kconfig |    2 +-
 1 files changed, 1 insertions(+), 1 deletions(-)

applies-to: 1bbe26c618a6afee3b59c2ad0fa2421a2ff617f3
f406db8cba6bbce42b96490e6d31bdec229ad994
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index 1958d9e..e70315a 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -447,7 +447,7 @@ config NET_SB1250_MAC
 
 config SGI_IOC3_ETH
 	bool "SGI IOC3 Ethernet"
-	depends on NET_ETHERNET && PCI && SGI_IP27 && BROKEN
+	depends on NET_ETHERNET && PCI && SGI_IP27
 	select CRC32
 	select MII
 	help
---
0.99.8.GIT




More information about the fedora-cvs-commits mailing list