From 2e124a00ddea4de857bb3a8855d6bda9db30f629 Mon Sep 17 00:00:00 2001 From: Adrian Bunk Date: Mon, 9 Jan 2006 18:34:08 -0800 Subject: [PATCH] --- yaml --- r: 21131 b: refs/heads/master c: e03d72b99e4027504ada134bf1804d6ea792b206 h: refs/heads/master i: 21129: ad166e3a98ee7decd4dd79944944da845aff294b 21127: 9a9583bcd56358ecd5e00f3acc1737571098bed3 v: v3 --- [refs] | 2 +- trunk/MAINTAINERS | 8 +- trunk/drivers/net/e100.c | 142 +-- trunk/drivers/net/e1000/e1000.h | 51 +- trunk/drivers/net/e1000/e1000_ethtool.c | 167 ++-- trunk/drivers/net/e1000/e1000_hw.c | 53 +- trunk/drivers/net/e1000/e1000_hw.h | 25 +- trunk/drivers/net/e1000/e1000_main.c | 814 ++++++------------ trunk/drivers/net/e1000/e1000_param.c | 14 +- trunk/drivers/net/mv643xx_eth.c | 680 ++++++--------- trunk/drivers/net/sk98lin/h/skaddr.h | 48 -- trunk/drivers/net/sk98lin/h/skcsum.h | 6 - trunk/drivers/net/sk98lin/h/skgeinit.h | 56 -- trunk/drivers/net/sk98lin/h/skgepnmi.h | 4 - trunk/drivers/net/sk98lin/h/skgesirq.h | 1 - trunk/drivers/net/sk98lin/h/ski2c.h | 3 - trunk/drivers/net/sk98lin/h/skvpd.h | 15 - trunk/drivers/net/sk98lin/skaddr.c | 35 +- trunk/drivers/net/sk98lin/skgeinit.c | 148 +--- trunk/drivers/net/sk98lin/skgemib.c | 7 - trunk/drivers/net/sk98lin/skgepnmi.c | 153 +--- trunk/drivers/net/sk98lin/skgesirq.c | 24 +- trunk/drivers/net/sk98lin/ski2c.c | 6 +- trunk/drivers/net/sk98lin/sklm80.c | 72 -- trunk/drivers/net/sk98lin/skrlmt.c | 1 - trunk/drivers/net/sk98lin/skvpd.c | 108 +-- trunk/drivers/net/sk98lin/skxmac2.c | 461 +--------- trunk/drivers/net/spider_net.c | 512 ++++++----- trunk/drivers/net/spider_net.h | 75 +- trunk/drivers/net/spider_net_ethtool.c | 19 - trunk/drivers/net/starfire.c | 36 - trunk/drivers/net/wireless/airo.c | 21 +- trunk/drivers/net/wireless/atmel.c | 4 +- trunk/drivers/net/wireless/hostap/Kconfig | 22 +- trunk/drivers/net/wireless/hostap/Makefile | 3 +- trunk/drivers/net/wireless/hostap/hostap.h | 37 - .../net/wireless/hostap/hostap_80211.h | 3 - .../net/wireless/hostap/hostap_80211_rx.c | 11 - .../net/wireless/hostap/hostap_80211_tx.c | 15 - trunk/drivers/net/wireless/hostap/hostap_ap.c | 36 +- trunk/drivers/net/wireless/hostap/hostap_ap.h | 2 - .../net/wireless/hostap/hostap_common.h | 3 - .../net/wireless/hostap/hostap_config.h | 13 +- .../drivers/net/wireless/hostap/hostap_info.c | 3 - .../net/wireless/hostap/hostap_ioctl.c | 12 +- .../drivers/net/wireless/hostap/hostap_main.c | 60 +- .../drivers/net/wireless/hostap/hostap_proc.c | 7 - .../drivers/net/wireless/hostap/hostap_wlan.h | 4 - trunk/drivers/net/wireless/ipw2100.c | 434 ++++++++++ trunk/drivers/net/wireless/ipw2200.c | 14 +- .../drivers/net/wireless/prism54/isl_ioctl.c | 2 +- .../drivers/net/wireless/prism54/islpci_eth.c | 2 +- trunk/drivers/net/wireless/ray_cs.c | 2 +- trunk/drivers/net/wireless/wavelan_cs.c | 2 +- trunk/include/net/ieee80211_crypt.h | 1 - trunk/include/net/iw_handler.h | 2 +- 56 files changed, 1532 insertions(+), 2929 deletions(-) diff --git a/[refs] b/[refs] index bae44cc55e2b..4a040f75fe95 100644 --- a/[refs] +++ b/[refs] @@ -1,2 +1,2 @@ --- -refs/heads/master: d4fbeabbc9e68c80738fe59135d201c3ed5fe40f +refs/heads/master: e03d72b99e4027504ada134bf1804d6ea792b206 diff --git a/trunk/MAINTAINERS b/trunk/MAINTAINERS index ff16eac8cf5b..6d1b048c62a1 100644 --- a/trunk/MAINTAINERS +++ b/trunk/MAINTAINERS @@ -1696,13 +1696,11 @@ M: mtk-manpages@gmx.net W: ftp://ftp.kernel.org/pub/linux/docs/manpages S: Maintained -MARVELL MV643XX ETHERNET DRIVER -P: Dale Farnsworth -M: dale@farnsworth.org +MARVELL MV64340 ETHERNET DRIVER P: Manish Lachwani -M: mlachwani@mvista.com +L: linux-mips@linux-mips.org L: netdev@vger.kernel.org -S: Odd Fixes for 2.4; Maintained for 2.6. +S: Supported MATROX FRAMEBUFFER DRIVER P: Petr Vandrovec diff --git a/trunk/drivers/net/e100.c b/trunk/drivers/net/e100.c index bf1fd2b98bf8..4726722a0635 100644 --- a/trunk/drivers/net/e100.c +++ b/trunk/drivers/net/e100.c @@ -1,25 +1,25 @@ /******************************************************************************* - + Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - - This program is free software; you can redistribute it and/or modify it - under the terms of the GNU General Public License as published by the Free - Software Foundation; either version 2 of the License, or (at your option) + + This program is free software; you can redistribute it and/or modify it + under the terms of the GNU General Public License as published by the Free + Software Foundation; either version 2 of the License, or (at your option) any later version. - - This program is distributed in the hope that it will be useful, but WITHOUT - ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or - FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + + This program is distributed in the hope that it will be useful, but WITHOUT + ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. - + You should have received a copy of the GNU General Public License along with - this program; if not, write to the Free Software Foundation, Inc., 59 + this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. - + The full GNU General Public License is included in this distribution in the file called LICENSE. - + Contact Information: Linux NICS Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497 @@ -160,7 +160,7 @@ #define DRV_NAME "e100" #define DRV_EXT "-NAPI" -#define DRV_VERSION "3.5.10-k2"DRV_EXT +#define DRV_VERSION "3.4.14-k4"DRV_EXT #define DRV_DESCRIPTION "Intel(R) PRO/100 Network Driver" #define DRV_COPYRIGHT "Copyright(c) 1999-2005 Intel Corporation" #define PFX DRV_NAME ": " @@ -320,7 +320,7 @@ enum cuc_dump { cuc_dump_complete = 0x0000A005, cuc_dump_reset_complete = 0x0000A007, }; - + enum port { software_reset = 0x0000, selftest = 0x0001, @@ -715,10 +715,10 @@ static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr) ctrl = (cmd_addr_data & (1 << i)) ? eecs | eedi : eecs; writeb(ctrl, &nic->csr->eeprom_ctrl_lo); e100_write_flush(nic); udelay(4); - + writeb(ctrl | eesk, &nic->csr->eeprom_ctrl_lo); e100_write_flush(nic); udelay(4); - + /* Eeprom drives a dummy zero to EEDO after receiving * complete address. Use this to adjust addr_len. */ ctrl = readb(&nic->csr->eeprom_ctrl_lo); @@ -726,7 +726,7 @@ static u16 e100_eeprom_read(struct nic *nic, u16 *addr_len, u16 addr) *addr_len -= (i - 16); i = 17; } - + data = (data << 1) | (ctrl & eedo ? 1 : 0); } @@ -1170,7 +1170,7 @@ static void e100_configure(struct nic *nic, struct cb *cb, struct sk_buff *skb) 0x00000000, 0x00000000, 0x00000000, 0x00000000, \ } -static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) +static void e100_load_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb) { /* *INDENT-OFF* */ static struct { @@ -1213,13 +1213,13 @@ static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb * driver can change the algorithm. * * INTDELAY - This loads the dead-man timer with its inital value. -* When this timer expires the interrupt is asserted, and the +* When this timer expires the interrupt is asserted, and the * timer is reset each time a new packet is received. (see * BUNDLEMAX below to set the limit on number of chained packets) * The current default is 0x600 or 1536. Experiments show that * the value should probably stay within the 0x200 - 0x1000. * -* BUNDLEMAX - +* BUNDLEMAX - * This sets the maximum number of frames that will be bundled. In * some situations, such as the TCP windowing algorithm, it may be * better to limit the growth of the bundle size than let it go as @@ -1229,7 +1229,7 @@ static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb * an interrupt for every frame received. If you do not want to put * a limit on the bundle size, set this value to xFFFF. * -* BUNDLESMALL - +* BUNDLESMALL - * This contains a bit-mask describing the minimum size frame that * will be bundled. The default masks the lower 7 bits, which means * that any frame less than 128 bytes in length will not be bundled, @@ -1244,7 +1244,7 @@ static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb * * The current default is 0xFF80, which masks out the lower 7 bits. * This means that any frame which is x7F (127) bytes or smaller -* will cause an immediate interrupt. Because this value must be a +* will cause an immediate interrupt. Because this value must be a * bit mask, there are only a few valid values that can be used. To * turn this feature off, the driver can write the value xFFFF to the * lower word of this instruction (in the same way that the other @@ -1253,7 +1253,7 @@ static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb * standard Ethernet frames are <= 2047 bytes in length. *************************************************************************/ -/* if you wish to disable the ucode functionality, while maintaining the +/* if you wish to disable the ucode functionality, while maintaining the * workarounds it provides, set the following defines to: * BUNDLESMALL 0 * BUNDLEMAX 1 @@ -1284,46 +1284,12 @@ static void e100_setup_ucode(struct nic *nic, struct cb *cb, struct sk_buff *skb for (i = 0; i < UCODE_SIZE; i++) cb->u.ucode[i] = cpu_to_le32(ucode[i]); - cb->command = cpu_to_le16(cb_ucode | cb_el); + cb->command = cpu_to_le16(cb_ucode); return; } noloaducode: - cb->command = cpu_to_le16(cb_nop | cb_el); -} - -static inline int e100_exec_cb_wait(struct nic *nic, struct sk_buff *skb, - void (*cb_prepare)(struct nic *, struct cb *, struct sk_buff *)) -{ - int err = 0, counter = 50; - struct cb *cb = nic->cb_to_clean; - - if ((err = e100_exec_cb(nic, NULL, e100_setup_ucode))) - DPRINTK(PROBE,ERR, "ucode cmd failed with error %d\n", err); - - /* must restart cuc */ - nic->cuc_cmd = cuc_start; - - /* wait for completion */ - e100_write_flush(nic); - udelay(10); - - /* wait for possibly (ouch) 500ms */ - while (!(cb->status & cpu_to_le16(cb_complete))) { - msleep(10); - if (!--counter) break; - } - - /* ack any interupts, something could have been set */ - writeb(~0, &nic->csr->scb.stat_ack); - - /* if the command failed, or is not OK, notify and return */ - if (!counter || !(cb->status & cpu_to_le16(cb_ok))) { - DPRINTK(PROBE,ERR, "ucode load failed\n"); - err = -EPERM; - } - - return err; + cb->command = cpu_to_le16(cb_nop); } static void e100_setup_iaaddr(struct nic *nic, struct cb *cb, @@ -1391,13 +1357,13 @@ static int e100_phy_init(struct nic *nic) mdio_write(netdev, nic->mii.phy_id, MII_NSC_CONG, cong); } - if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && + if((nic->mac >= mac_82550_D102) || ((nic->flags & ich) && (mdio_read(netdev, nic->mii.phy_id, MII_TPISTATUS) & 0x8000))) { /* enable/disable MDI/MDI-X auto-switching. MDI/MDI-X auto-switching is disabled for 82551ER/QM chips */ if((nic->mac == mac_82551_E) || (nic->mac == mac_82551_F) || - (nic->mac == mac_82551_10) || (nic->mii.force_media) || - !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled)) + (nic->mac == mac_82551_10) || (nic->mii.force_media) || + !(nic->eeprom[eeprom_cnfg_mdix] & eeprom_mdix_enabled)) mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, 0); else mdio_write(netdev, nic->mii.phy_id, MII_NCONFIG, NCONFIG_AUTO_SWITCH); @@ -1422,7 +1388,7 @@ static int e100_hw_init(struct nic *nic) return err; if((err = e100_exec_cmd(nic, ruc_load_base, 0))) return err; - if ((err = e100_exec_cb_wait(nic, NULL, e100_setup_ucode))) + if((err = e100_exec_cb(nic, NULL, e100_load_ucode))) return err; if((err = e100_exec_cb(nic, NULL, e100_configure))) return err; @@ -1527,7 +1493,7 @@ static void e100_update_stats(struct nic *nic) } } - + if(e100_exec_cmd(nic, cuc_dump_reset, 0)) DPRINTK(TX_ERR, DEBUG, "exec cuc_dump_reset failed\n"); } @@ -1576,10 +1542,10 @@ static void e100_watchdog(unsigned long data) mii_check_link(&nic->mii); /* Software generated interrupt to recover from (rare) Rx - * allocation failure. - * Unfortunately have to use a spinlock to not re-enable interrupts - * accidentally, due to hardware that shares a register between the - * interrupt mask bit and the SW Interrupt generation bit */ + * allocation failure. + * Unfortunately have to use a spinlock to not re-enable interrupts + * accidentally, due to hardware that shares a register between the + * interrupt mask bit and the SW Interrupt generation bit */ spin_lock_irq(&nic->cmd_lock); writeb(readb(&nic->csr->scb.cmd_hi) | irq_sw_gen,&nic->csr->scb.cmd_hi); spin_unlock_irq(&nic->cmd_lock); @@ -1864,7 +1830,7 @@ static void e100_rx_clean(struct nic *nic, unsigned int *work_done, struct rx *rx_to_start = NULL; /* are we already rnr? then pay attention!!! this ensures that - * the state machine progression never allows a start with a + * the state machine progression never allows a start with a * partially cleaned list, avoiding a race between hardware * and rx_to_clean when in NAPI mode */ if(RU_SUSPENDED == nic->ru_running) @@ -2100,7 +2066,7 @@ static void e100_tx_timeout(struct net_device *netdev) { struct nic *nic = netdev_priv(netdev); - /* Reset outside of interrupt context, to avoid request_irq + /* Reset outside of interrupt context, to avoid request_irq * in interrupt context */ schedule_work(&nic->tx_timeout_task); } @@ -2347,7 +2313,7 @@ static int e100_set_ringparam(struct net_device *netdev, struct param_range *rfds = &nic->params.rfds; struct param_range *cbs = &nic->params.cbs; - if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) + if ((ring->rx_mini_pending) || (ring->rx_jumbo_pending)) return -EINVAL; if(netif_running(netdev)) @@ -2665,9 +2631,7 @@ static int __devinit e100_probe(struct pci_dev *pdev, nic->flags |= wol_magic; /* ack any pending wake events, disable PME */ - err = pci_enable_wake(pdev, 0, 0); - if (err) - DPRINTK(PROBE, ERR, "Error clearing wake event\n"); + pci_enable_wake(pdev, 0, 0); strcpy(netdev->name, "eth%d"); if((err = register_netdev(netdev))) { @@ -2718,7 +2682,6 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); - int retval; if(netif_running(netdev)) e100_down(nic); @@ -2726,14 +2689,9 @@ static int e100_suspend(struct pci_dev *pdev, pm_message_t state) netif_device_detach(netdev); pci_save_state(pdev); - retval = pci_enable_wake(pdev, pci_choose_state(pdev, state), - nic->flags & (wol_magic | e100_asf(nic))); - if (retval) - DPRINTK(PROBE,ERR, "Error enabling wake\n"); + pci_enable_wake(pdev, pci_choose_state(pdev, state), nic->flags & (wol_magic | e100_asf(nic))); pci_disable_device(pdev); - retval = pci_set_power_state(pdev, pci_choose_state(pdev, state)); - if (retval) - DPRINTK(PROBE,ERR, "Error %d setting power state\n", retval); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } @@ -2742,16 +2700,11 @@ static int e100_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); - int retval; - retval = pci_set_power_state(pdev, PCI_D0); - if (retval) - DPRINTK(PROBE,ERR, "Error waking adapter\n"); + pci_set_power_state(pdev, PCI_D0); pci_restore_state(pdev); /* ack any pending wake events, disable PME */ - retval = pci_enable_wake(pdev, 0, 0); - if (retval) - DPRINTK(PROBE,ERR, "Error clearing wake events\n"); + pci_enable_wake(pdev, 0, 0); if(e100_hw_init(nic)) DPRINTK(HW, ERR, "e100_hw_init failed\n"); @@ -2768,15 +2721,12 @@ static void e100_shutdown(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct nic *nic = netdev_priv(netdev); - int retval; #ifdef CONFIG_PM - retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic))); + pci_enable_wake(pdev, 0, nic->flags & (wol_magic | e100_asf(nic))); #else - retval = pci_enable_wake(pdev, 0, nic->flags & (wol_magic)); + pci_enable_wake(pdev, 0, nic->flags & (wol_magic)); #endif - if (retval) - DPRINTK(PROBE,ERR, "Error enabling wake\n"); } @@ -2789,7 +2739,7 @@ static struct pci_driver e100_driver = { .suspend = e100_suspend, .resume = e100_resume, #endif - .shutdown = e100_shutdown, + .shutdown = e100_shutdown, }; static int __init e100_init_module(void) diff --git a/trunk/drivers/net/e1000/e1000.h b/trunk/drivers/net/e1000/e1000.h index 27c77306193b..e02e9ba2e18b 100644 --- a/trunk/drivers/net/e1000/e1000.h +++ b/trunk/drivers/net/e1000/e1000.h @@ -72,6 +72,10 @@ #include #include #include +#ifdef CONFIG_E1000_MQ +#include +#include +#endif #define BAR_0 0 #define BAR_1 1 @@ -83,10 +87,6 @@ struct e1000_adapter; #include "e1000_hw.h" -#ifdef CONFIG_E1000_MQ -#include -#include -#endif #ifdef DBG #define E1000_DBG(args...) printk(KERN_DEBUG "e1000: " args) @@ -169,13 +169,6 @@ struct e1000_buffer { uint16_t next_to_watch; }; -#ifdef CONFIG_E1000_MQ -struct e1000_queue_stats { - uint64_t packets; - uint64_t bytes; -}; -#endif - struct e1000_ps_page { struct page *ps_page[PS_PAGE_BUFFERS]; }; struct e1000_ps_page_dma { uint64_t ps_page_dma[PS_PAGE_BUFFERS]; }; @@ -198,12 +191,10 @@ struct e1000_tx_ring { spinlock_t tx_lock; uint16_t tdh; uint16_t tdt; + uint64_t pkt; boolean_t last_tx_tso; -#ifdef CONFIG_E1000_MQ - struct e1000_queue_stats tx_stats; -#endif }; struct e1000_rx_ring { @@ -225,17 +216,9 @@ struct e1000_rx_ring { struct e1000_ps_page *ps_page; struct e1000_ps_page_dma *ps_page_dma; - struct sk_buff *rx_skb_top; - struct sk_buff *rx_skb_prev; - - /* cpu for rx queue */ - int cpu; - uint16_t rdh; uint16_t rdt; -#ifdef CONFIG_E1000_MQ - struct e1000_queue_stats rx_stats; -#endif + uint64_t pkt; }; #define E1000_DESC_UNUSED(R) \ @@ -268,9 +251,6 @@ struct e1000_adapter { uint16_t link_speed; uint16_t link_duplex; spinlock_t stats_lock; -#ifdef CONFIG_E1000_NAPI - spinlock_t tx_queue_lock; -#endif atomic_t irq_sem; struct work_struct tx_timeout_task; struct work_struct watchdog_task; @@ -284,7 +264,6 @@ struct e1000_adapter { #ifdef CONFIG_E1000_MQ struct e1000_tx_ring **cpu_tx_ring; /* per-cpu */ #endif - unsigned long tx_queue_len; uint32_t txd_cmd; uint32_t tx_int_delay; uint32_t tx_abs_int_delay; @@ -292,11 +271,9 @@ struct e1000_adapter { uint64_t gotcl_old; uint64_t tpt_old; uint64_t colc_old; - uint32_t tx_timeout_count; uint32_t tx_fifo_head; uint32_t tx_head_addr; uint32_t tx_fifo_size; - uint8_t tx_timeout_factor; atomic_t tx_fifo_stall; boolean_t pcix_82544; boolean_t detect_tx_hung; @@ -304,15 +281,14 @@ struct e1000_adapter { /* RX */ #ifdef CONFIG_E1000_NAPI boolean_t (*clean_rx) (struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int *work_done, int work_to_do); + struct e1000_rx_ring *rx_ring, + int *work_done, int work_to_do); #else boolean_t (*clean_rx) (struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring); + struct e1000_rx_ring *rx_ring); #endif void (*alloc_rx_buf) (struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int cleaned_count); + 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 */ @@ -320,15 +296,13 @@ struct e1000_adapter { #ifdef CONFIG_E1000_MQ struct net_device **cpu_netdev; /* per-cpu */ struct call_async_data_struct rx_sched_call_data; - cpumask_t cpumask; + int cpu_for_queue[4]; #endif - int num_tx_queues; - int num_rx_queues; + int num_queues; uint64_t hw_csum_err; uint64_t hw_csum_good; uint64_t rx_hdr_split; - uint32_t alloc_rx_buff_failed; uint32_t rx_int_delay; uint32_t rx_abs_int_delay; boolean_t rx_csum; @@ -356,7 +330,6 @@ struct e1000_adapter { struct e1000_rx_ring test_rx_ring; - u32 *config_space; int msg_enable; #ifdef CONFIG_PCI_MSI boolean_t have_msi; diff --git a/trunk/drivers/net/e1000/e1000_ethtool.c b/trunk/drivers/net/e1000/e1000_ethtool.c index d252297e4db0..c88f1a3c1b1d 100644 --- a/trunk/drivers/net/e1000/e1000_ethtool.c +++ b/trunk/drivers/net/e1000/e1000_ethtool.c @@ -80,7 +80,6 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "tx_deferred_ok", E1000_STAT(stats.dc) }, { "tx_single_coll_ok", E1000_STAT(stats.scc) }, { "tx_multi_coll_ok", E1000_STAT(stats.mcc) }, - { "tx_timeout_count", E1000_STAT(tx_timeout_count) }, { "rx_long_length_errors", E1000_STAT(stats.roc) }, { "rx_short_length_errors", E1000_STAT(stats.ruc) }, { "rx_align_errors", E1000_STAT(stats.algnerrc) }, @@ -94,20 +93,9 @@ static const struct e1000_stats e1000_gstrings_stats[] = { { "rx_csum_offload_good", E1000_STAT(hw_csum_good) }, { "rx_csum_offload_errors", E1000_STAT(hw_csum_err) }, { "rx_header_split", E1000_STAT(rx_hdr_split) }, - { "alloc_rx_buff_failed", E1000_STAT(alloc_rx_buff_failed) }, }; - -#ifdef CONFIG_E1000_MQ -#define E1000_QUEUE_STATS_LEN \ - (((struct e1000_adapter *)netdev->priv)->num_tx_queues + \ - ((struct e1000_adapter *)netdev->priv)->num_rx_queues) \ - * (sizeof(struct e1000_queue_stats) / sizeof(uint64_t)) -#else -#define E1000_QUEUE_STATS_LEN 0 -#endif -#define E1000_GLOBAL_STATS_LEN \ +#define E1000_STATS_LEN \ sizeof(e1000_gstrings_stats) / sizeof(struct e1000_stats) -#define E1000_STATS_LEN (E1000_GLOBAL_STATS_LEN + E1000_QUEUE_STATS_LEN) static const char e1000_gstrings_test[][ETH_GSTRING_LEN] = { "Register test (offline)", "Eeprom test (offline)", "Interrupt test (offline)", "Loopback test (offline)", @@ -195,15 +183,7 @@ e1000_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd) struct e1000_adapter *adapter = netdev_priv(netdev); struct e1000_hw *hw = &adapter->hw; - /* When SoL/IDER sessions are active, autoneg/speed/duplex - * cannot be changed */ - if (e1000_check_phy_reset_block(hw)) { - DPRINTK(DRV, ERR, "Cannot change link characteristics " - "when SoL/IDER is active.\n"); - return -EINVAL; - } - - if (ecmd->autoneg == AUTONEG_ENABLE) { + if(ecmd->autoneg == AUTONEG_ENABLE) { hw->autoneg = 1; if(hw->media_type == e1000_media_type_fiber) hw->autoneg_advertised = ADVERTISED_1000baseT_Full | @@ -587,21 +567,21 @@ e1000_get_drvinfo(struct net_device *netdev, strncpy(drvinfo->driver, e1000_driver_name, 32); strncpy(drvinfo->version, e1000_driver_version, 32); - - /* EEPROM image version # is reported as firmware version # for + + /* EEPROM image version # is reported as firware version # for * 8257{1|2|3} controllers */ e1000_read_eeprom(&adapter->hw, 5, 1, &eeprom_data); switch (adapter->hw.mac_type) { case e1000_82571: case e1000_82572: case e1000_82573: - sprintf(firmware_version, "%d.%d-%d", + sprintf(firmware_version, "%d.%d-%d", (eeprom_data & 0xF000) >> 12, (eeprom_data & 0x0FF0) >> 4, eeprom_data & 0x000F); break; default: - sprintf(firmware_version, "N/A"); + sprintf(firmware_version, "n/a"); } strncpy(drvinfo->fw_version, firmware_version, 32); @@ -643,8 +623,8 @@ e1000_set_ringparam(struct net_device *netdev, 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_tx_queues; - rx_ring_size = sizeof(struct e1000_rx_ring) * adapter->num_rx_queues; + 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); @@ -683,10 +663,10 @@ e1000_set_ringparam(struct net_device *netdev, E1000_MAX_TXD : E1000_MAX_82544_TXD)); E1000_ROUNDUP(txdr->count, REQ_TX_DESCRIPTOR_MULTIPLE); - for (i = 0; i < adapter->num_tx_queues; i++) + for (i = 0; i < adapter->num_queues; i++) { txdr[i].count = txdr->count; - for (i = 0; i < adapter->num_rx_queues; i++) rxdr[i].count = rxdr->count; + } if(netif_running(adapter->netdev)) { /* Try to get new resources before deleting old */ @@ -999,17 +979,18 @@ e1000_free_desc_rings(struct e1000_adapter *adapter) } } - if (txdr->desc) { + if(txdr->desc) { pci_free_consistent(pdev, txdr->size, txdr->desc, txdr->dma); txdr->desc = NULL; } - if (rxdr->desc) { + if(rxdr->desc) { pci_free_consistent(pdev, rxdr->size, rxdr->desc, rxdr->dma); rxdr->desc = NULL; } kfree(txdr->buffer_info); txdr->buffer_info = NULL; + kfree(rxdr->buffer_info); rxdr->buffer_info = NULL; @@ -1346,11 +1327,11 @@ e1000_set_phy_loopback(struct e1000_adapter *adapter) static int e1000_setup_loopback_test(struct e1000_adapter *adapter) { - struct e1000_hw *hw = &adapter->hw; uint32_t rctl; + struct e1000_hw *hw = &adapter->hw; if (hw->media_type == e1000_media_type_fiber || - hw->media_type == e1000_media_type_internal_serdes) { + hw->media_type == e1000_media_type_internal_serdes) { switch (hw->mac_type) { case e1000_82545: case e1000_82546: @@ -1381,25 +1362,25 @@ e1000_setup_loopback_test(struct e1000_adapter *adapter) static void e1000_loopback_cleanup(struct e1000_adapter *adapter) { - struct e1000_hw *hw = &adapter->hw; uint32_t rctl; uint16_t phy_reg; + struct e1000_hw *hw = &adapter->hw; - rctl = E1000_READ_REG(hw, RCTL); + rctl = E1000_READ_REG(&adapter->hw, RCTL); rctl &= ~(E1000_RCTL_LBM_TCVR | E1000_RCTL_LBM_MAC); - E1000_WRITE_REG(hw, RCTL, rctl); + E1000_WRITE_REG(&adapter->hw, RCTL, rctl); switch (hw->mac_type) { case e1000_82571: case e1000_82572: if (hw->media_type == e1000_media_type_fiber || - hw->media_type == e1000_media_type_internal_serdes) { + hw->media_type == e1000_media_type_internal_serdes){ #define E1000_SERDES_LB_OFF 0x400 E1000_WRITE_REG(hw, SCTL, E1000_SERDES_LB_OFF); msec_delay(10); break; } - /* Fall Through */ + /* fall thru for Cu adapters */ case e1000_82545: case e1000_82546: case e1000_82545_rev_3: @@ -1420,7 +1401,7 @@ static void e1000_create_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) { memset(skb->data, 0xFF, frame_size); - frame_size &= ~1; + frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size; memset(&skb->data[frame_size / 2], 0xAA, frame_size / 2 - 1); memset(&skb->data[frame_size / 2 + 10], 0xBE, 1); memset(&skb->data[frame_size / 2 + 12], 0xAF, 1); @@ -1429,7 +1410,7 @@ e1000_create_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) static int e1000_check_lbtest_frame(struct sk_buff *skb, unsigned int frame_size) { - frame_size &= ~1; + frame_size = (frame_size % 2) ? (frame_size - 1) : frame_size; if(*(skb->data + 3) == 0xFF) { if((*(skb->data + frame_size / 2 + 10) == 0xBE) && (*(skb->data + frame_size / 2 + 12) == 0xAF)) { @@ -1507,25 +1488,14 @@ e1000_run_loopback_test(struct e1000_adapter *adapter) static int e1000_loopback_test(struct e1000_adapter *adapter, uint64_t *data) { - /* PHY loopback cannot be performed if SoL/IDER - * sessions are active */ - if (e1000_check_phy_reset_block(&adapter->hw)) { - DPRINTK(DRV, ERR, "Cannot do PHY loopback test " - "when SoL/IDER is active.\n"); - *data = 0; - goto out; - } - - if ((*data = e1000_setup_desc_rings(adapter))) - goto out; - if ((*data = e1000_setup_loopback_test(adapter))) - goto err_loopback; + if((*data = e1000_setup_desc_rings(adapter))) goto err_loopback; + if((*data = e1000_setup_loopback_test(adapter))) + goto err_loopback_setup; *data = e1000_run_loopback_test(adapter); e1000_loopback_cleanup(adapter); - -err_loopback: +err_loopback_setup: e1000_free_desc_rings(adapter); -out: +err_loopback: return *data; } @@ -1647,7 +1617,6 @@ e1000_get_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) case E1000_DEV_ID_82546EB_FIBER: case E1000_DEV_ID_82546GB_FIBER: - case E1000_DEV_ID_82571EB_FIBER: /* Wake events only supported on port A for dual fiber */ if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) { wol->supported = 0; @@ -1691,7 +1660,6 @@ e1000_set_wol(struct net_device *netdev, struct ethtool_wolinfo *wol) case E1000_DEV_ID_82546EB_FIBER: case E1000_DEV_ID_82546GB_FIBER: - case E1000_DEV_ID_82571EB_FIBER: /* Wake events only supported on port A for dual fiber */ if(E1000_READ_REG(hw, STATUS) & E1000_STATUS_FUNC_1) return wol->wolopts ? -EOPNOTSUPP : 0; @@ -1753,21 +1721,21 @@ e1000_phys_id(struct net_device *netdev, uint32_t data) mod_timer(&adapter->blink_timer, jiffies); msleep_interruptible(data * 1000); del_timer_sync(&adapter->blink_timer); - } else if (adapter->hw.mac_type < e1000_82573) { - E1000_WRITE_REG(&adapter->hw, LEDCTL, - (E1000_LEDCTL_LED2_BLINK_RATE | - E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK | - (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) | - (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) | - (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT))); + } + else if(adapter->hw.mac_type < e1000_82573) { + E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE | + E1000_LEDCTL_LED0_BLINK | E1000_LEDCTL_LED2_BLINK | + (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) | + (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED0_MODE_SHIFT) | + (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED1_MODE_SHIFT))); msleep_interruptible(data * 1000); - } else { - E1000_WRITE_REG(&adapter->hw, LEDCTL, - (E1000_LEDCTL_LED2_BLINK_RATE | - E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | - (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) | - (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) | - (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT))); + } + else { + E1000_WRITE_REG(&adapter->hw, LEDCTL, (E1000_LEDCTL_LED2_BLINK_RATE | + E1000_LEDCTL_LED1_BLINK | E1000_LEDCTL_LED2_BLINK | + (E1000_LEDCTL_MODE_LED_ON << E1000_LEDCTL_LED2_MODE_SHIFT) | + (E1000_LEDCTL_MODE_LINK_ACTIVITY << E1000_LEDCTL_LED1_MODE_SHIFT) | + (E1000_LEDCTL_MODE_LED_OFF << E1000_LEDCTL_LED0_MODE_SHIFT))); msleep_interruptible(data * 1000); } @@ -1800,43 +1768,19 @@ e1000_get_ethtool_stats(struct net_device *netdev, struct ethtool_stats *stats, uint64_t *data) { struct e1000_adapter *adapter = netdev_priv(netdev); -#ifdef CONFIG_E1000_MQ - uint64_t *queue_stat; - int stat_count = sizeof(struct e1000_queue_stats) / sizeof(uint64_t); - int j, k; -#endif int i; e1000_update_stats(adapter); - for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { - char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset; - data[i] = (e1000_gstrings_stats[i].sizeof_stat == + for(i = 0; i < E1000_STATS_LEN; i++) { + char *p = (char *)adapter+e1000_gstrings_stats[i].stat_offset; + data[i] = (e1000_gstrings_stats[i].sizeof_stat == sizeof(uint64_t)) ? *(uint64_t *)p : *(uint32_t *)p; } -#ifdef CONFIG_E1000_MQ - for (j = 0; j < adapter->num_tx_queues; j++) { - queue_stat = (uint64_t *)&adapter->tx_ring[j].tx_stats; - for (k = 0; k < stat_count; k++) - data[i + k] = queue_stat[k]; - i += k; - } - for (j = 0; j < adapter->num_rx_queues; j++) { - queue_stat = (uint64_t *)&adapter->rx_ring[j].rx_stats; - for (k = 0; k < stat_count; k++) - data[i + k] = queue_stat[k]; - i += k; - } -#endif -/* BUG_ON(i != E1000_STATS_LEN); */ } static void e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) { -#ifdef CONFIG_E1000_MQ - struct e1000_adapter *adapter = netdev_priv(netdev); -#endif - uint8_t *p = data; int i; switch(stringset) { @@ -1845,26 +1789,11 @@ e1000_get_strings(struct net_device *netdev, uint32_t stringset, uint8_t *data) E1000_TEST_LEN*ETH_GSTRING_LEN); break; case ETH_SS_STATS: - for (i = 0; i < E1000_GLOBAL_STATS_LEN; i++) { - memcpy(p, e1000_gstrings_stats[i].stat_string, - ETH_GSTRING_LEN); - p += ETH_GSTRING_LEN; - } -#ifdef CONFIG_E1000_MQ - for (i = 0; i < adapter->num_tx_queues; i++) { - sprintf(p, "tx_queue_%u_packets", i); - p += ETH_GSTRING_LEN; - sprintf(p, "tx_queue_%u_bytes", i); - p += ETH_GSTRING_LEN; + for (i=0; i < E1000_STATS_LEN; i++) { + memcpy(data + i * ETH_GSTRING_LEN, + e1000_gstrings_stats[i].stat_string, + ETH_GSTRING_LEN); } - for (i = 0; i < adapter->num_rx_queues; i++) { - sprintf(p, "rx_queue_%u_packets", i); - p += ETH_GSTRING_LEN; - sprintf(p, "rx_queue_%u_bytes", i); - p += ETH_GSTRING_LEN; - } -#endif -/* BUG_ON(p - data != E1000_STATS_LEN * ETH_GSTRING_LEN); */ break; } } diff --git a/trunk/drivers/net/e1000/e1000_hw.c b/trunk/drivers/net/e1000/e1000_hw.c index 2437d362ff63..136fc031e4ad 100644 --- a/trunk/drivers/net/e1000/e1000_hw.c +++ b/trunk/drivers/net/e1000/e1000_hw.c @@ -318,8 +318,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: - case E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3: hw->mac_type = e1000_82546_rev_3; break; case E1000_DEV_ID_82541EI: @@ -641,7 +639,6 @@ e1000_init_hw(struct e1000_hw *hw) uint16_t cmd_mmrbc; uint16_t stat_mmrbc; uint32_t mta_size; - uint32_t ctrl_ext; DEBUGFUNC("e1000_init_hw"); @@ -738,6 +735,7 @@ e1000_init_hw(struct e1000_hw *hw) break; case e1000_82571: case e1000_82572: + ctrl |= (1 << 22); case e1000_82573: ctrl |= E1000_TXDCTL_COUNT_DESC; break; @@ -777,15 +775,6 @@ e1000_init_hw(struct e1000_hw *hw) */ e1000_clear_hw_cntrs(hw); - if (hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER || - hw->device_id == E1000_DEV_ID_82546GB_QUAD_COPPER_KSP3) { - ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); - /* Relaxed ordering must be disabled to avoid a parity - * error crash in a PCI slot. */ - ctrl_ext |= E1000_CTRL_EXT_RO_DIS; - E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - } - return ret_val; } @@ -849,11 +838,6 @@ e1000_setup_link(struct e1000_hw *hw) DEBUGFUNC("e1000_setup_link"); - /* In the case of the phy reset being blocked, we already have a link. - * We do not have to set it up again. */ - if (e1000_check_phy_reset_block(hw)) - return E1000_SUCCESS; - /* Read and store word 0x0F of the EEPROM. This word contains bits * that determine the hardware's default PAUSE (flow control) mode, * a bit that determines whether the HW defaults to enabling or @@ -1945,19 +1929,14 @@ e1000_phy_force_speed_duplex(struct e1000_hw *hw) void e1000_config_collision_dist(struct e1000_hw *hw) { - uint32_t tctl, coll_dist; + uint32_t tctl; DEBUGFUNC("e1000_config_collision_dist"); - if (hw->mac_type < e1000_82543) - coll_dist = E1000_COLLISION_DISTANCE_82542; - else - coll_dist = E1000_COLLISION_DISTANCE; - tctl = E1000_READ_REG(hw, TCTL); tctl &= ~E1000_TCTL_COLD; - tctl |= coll_dist << E1000_COLD_SHIFT; + tctl |= E1000_COLLISION_DISTANCE << E1000_COLD_SHIFT; E1000_WRITE_REG(hw, TCTL, tctl); E1000_WRITE_FLUSH(hw); @@ -3003,8 +2982,6 @@ e1000_phy_hw_reset(struct e1000_hw *hw) if (hw->mac_type < e1000_82571) msec_delay(10); - else - udelay(100); E1000_WRITE_REG(hw, CTRL, ctrl); E1000_WRITE_FLUSH(hw); @@ -3904,16 +3881,14 @@ e1000_read_eeprom(struct e1000_hw *hw, return -E1000_ERR_EEPROM; } - /* FLASH reads without acquiring the semaphore are safe */ - if (e1000_is_onboard_nvm_eeprom(hw) == TRUE && - hw->eeprom.use_eerd == FALSE) { - switch (hw->mac_type) { - default: - /* Prepare the EEPROM for reading */ - if (e1000_acquire_eeprom(hw) != E1000_SUCCESS) - return -E1000_ERR_EEPROM; - break; - } + /* FLASH reads without acquiring the semaphore are safe in 82573-based + * controllers. + */ + if ((e1000_is_onboard_nvm_eeprom(hw) == TRUE) || + (hw->mac_type != e1000_82573)) { + /* Prepare the EEPROM for reading */ + if(e1000_acquire_eeprom(hw) != E1000_SUCCESS) + return -E1000_ERR_EEPROM; } if(eeprom->use_eerd == TRUE) { @@ -6745,12 +6720,6 @@ e1000_get_phy_cfg_done(struct e1000_hw *hw) break; } - /* PHY configuration from NVM just starts after EECD_AUTO_RD sets to high. - * Need to wait for PHY configuration completion before accessing NVM - * and PHY. */ - if (hw->mac_type == e1000_82573) - msec_delay(25); - return E1000_SUCCESS; } diff --git a/trunk/drivers/net/e1000/e1000_hw.h b/trunk/drivers/net/e1000/e1000_hw.h index 0b8f6f2b774b..7caa35748cea 100644 --- a/trunk/drivers/net/e1000/e1000_hw.h +++ b/trunk/drivers/net/e1000/e1000_hw.h @@ -439,7 +439,6 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); #define E1000_DEV_ID_82546GB_FIBER 0x107A #define E1000_DEV_ID_82546GB_SERDES 0x107B #define E1000_DEV_ID_82546GB_PCIE 0x108A -#define E1000_DEV_ID_82546GB_QUAD_COPPER 0x1099 #define E1000_DEV_ID_82547EI 0x1019 #define E1000_DEV_ID_82571EB_COPPER 0x105E #define E1000_DEV_ID_82571EB_FIBER 0x105F @@ -450,7 +449,6 @@ int32_t e1000_check_phy_reset_block(struct e1000_hw *hw); #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_KSP3 0x10B5 #define NODE_ADDRESS_SIZE 6 @@ -1499,7 +1497,6 @@ struct e1000_hw { #define E1000_CTRL_EXT_EE_RST 0x00002000 /* Reinitialize from EEPROM */ #define E1000_CTRL_EXT_IPS 0x00004000 /* Invert Power State */ #define E1000_CTRL_EXT_SPD_BYPS 0x00008000 /* Speed Select Bypass */ -#define E1000_CTRL_EXT_RO_DIS 0x00020000 /* Relaxed Ordering disable */ #define E1000_CTRL_EXT_LINK_MODE_MASK 0x00C00000 #define E1000_CTRL_EXT_LINK_MODE_GMII 0x00000000 #define E1000_CTRL_EXT_LINK_MODE_TBI 0x00C00000 @@ -1957,23 +1954,6 @@ struct e1000_host_command_info { #define E1000_MDALIGN 4096 -/* PCI-Ex registers */ - -/* PCI-Ex Control Register */ -#define E1000_GCR_RXD_NO_SNOOP 0x00000001 -#define E1000_GCR_RXDSCW_NO_SNOOP 0x00000002 -#define E1000_GCR_RXDSCR_NO_SNOOP 0x00000004 -#define E1000_GCR_TXD_NO_SNOOP 0x00000008 -#define E1000_GCR_TXDSCW_NO_SNOOP 0x00000010 -#define E1000_GCR_TXDSCR_NO_SNOOP 0x00000020 - -#define PCI_EX_NO_SNOOP_ALL (E1000_GCR_RXD_NO_SNOOP | \ - E1000_GCR_RXDSCW_NO_SNOOP | \ - E1000_GCR_RXDSCR_NO_SNOOP | \ - E1000_GCR TXD_NO_SNOOP | \ - E1000_GCR_TXDSCW_NO_SNOOP | \ - E1000_GCR_TXDSCR_NO_SNOOP) - #define E1000_GCR_L1_ACT_WITHOUT_L0S_RX 0x08000000 /* Function Active and Power State to MNG */ #define E1000_FACTPS_FUNC0_POWER_STATE_MASK 0x00000003 @@ -2097,10 +2077,7 @@ struct e1000_host_command_info { /* Collision related configuration parameters */ #define E1000_COLLISION_THRESHOLD 15 #define E1000_CT_SHIFT 4 -/* Collision distance is a 0-based value that applies to - * half-duplex-capable hardware only. */ -#define E1000_COLLISION_DISTANCE 63 -#define E1000_COLLISION_DISTANCE_82542 64 +#define E1000_COLLISION_DISTANCE 64 #define E1000_FDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE #define E1000_HDX_COLLISION_DISTANCE E1000_COLLISION_DISTANCE #define E1000_COLD_SHIFT 12 diff --git a/trunk/drivers/net/e1000/e1000_main.c b/trunk/drivers/net/e1000/e1000_main.c index d0a5d1656c5f..438a931fd55d 100644 --- a/trunk/drivers/net/e1000/e1000_main.c +++ b/trunk/drivers/net/e1000/e1000_main.c @@ -43,7 +43,7 @@ static char e1000_driver_string[] = "Intel(R) PRO/1000 Network Driver"; #else #define DRIVERNAPI "-NAPI" #endif -#define DRV_VERSION "6.3.9-k2"DRIVERNAPI +#define DRV_VERSION "6.1.16-k2"DRIVERNAPI char e1000_driver_version[] = DRV_VERSION; static char e1000_copyright[] = "Copyright (c) 1999-2005 Intel Corporation."; @@ -97,9 +97,7 @@ static struct pci_device_id e1000_pci_tbl[] = { 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), - INTEL_E1000_ETHERNET_DEVICE(0x10B5), /* required last entry */ {0,} }; @@ -173,11 +171,9 @@ 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, - struct e1000_rx_ring *rx_ring, - int cleaned_count); + struct e1000_rx_ring *rx_ring); static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int cleaned_count); + 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); @@ -323,75 +319,7 @@ e1000_update_mng_vlan(struct e1000_adapter *adapter) } } } - -/** - * e1000_release_hw_control - release control of the h/w to f/w - * @adapter: address of board private structure - * - * e1000_release_hw_control resets {CTRL_EXT|FWSM}:DRV_LOAD bit. - * For ASF and Pass Through versions of f/w this means that the - * driver is no longer loaded. For AMT version (only with 82573) i - * of the f/w this means that the netowrk i/f is closed. - * - **/ - -static inline void -e1000_release_hw_control(struct e1000_adapter *adapter) -{ - uint32_t ctrl_ext; - uint32_t swsm; - - /* Let firmware taken over control of h/w */ - 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, - swsm & ~E1000_SWSM_DRV_LOAD); - default: - break; - } -} - -/** - * e1000_get_hw_control - get control of the h/w from f/w - * @adapter: address of board private structure - * - * e1000_get_hw_control sets {CTRL_EXT|FWSM}:DRV_LOAD bit. - * For ASF and Pass Through versions of f/w this means that - * the driver is loaded. For AMT version (only with 82573) - * of the f/w this means that the netowrk i/f is open. - * - **/ - -static inline void -e1000_get_hw_control(struct e1000_adapter *adapter) -{ - uint32_t ctrl_ext; - uint32_t swsm; - /* 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, - swsm | E1000_SWSM_DRV_LOAD); - break; - default: - break; - } -} - + int e1000_up(struct e1000_adapter *adapter) { @@ -415,14 +343,8 @@ e1000_up(struct e1000_adapter *adapter) e1000_configure_tx(adapter); e1000_setup_rctl(adapter); e1000_configure_rx(adapter); - /* call E1000_DESC_UNUSED which always leaves - * at least 1 descriptor unused to make sure - * next_to_use != next_to_clean */ - for (i = 0; i < adapter->num_rx_queues; i++) { - struct e1000_rx_ring *ring = &adapter->rx_ring[i]; - adapter->alloc_rx_buf(adapter, ring, - E1000_DESC_UNUSED(ring)); - } + 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) { @@ -442,12 +364,6 @@ e1000_up(struct e1000_adapter *adapter) return err; } -#ifdef CONFIG_E1000_MQ - e1000_setup_queue_mapping(adapter); -#endif - - adapter->tx_queue_len = netdev->tx_queue_len; - mod_timer(&adapter->watchdog_timer, jiffies); #ifdef CONFIG_E1000_NAPI @@ -462,8 +378,6 @@ void e1000_down(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; - boolean_t mng_mode_enabled = (adapter->hw.mac_type >= e1000_82571) && - e1000_check_mng_mode(&adapter->hw); e1000_irq_disable(adapter); #ifdef CONFIG_E1000_MQ @@ -482,7 +396,6 @@ e1000_down(struct e1000_adapter *adapter) #ifdef CONFIG_E1000_NAPI netif_poll_disable(netdev); #endif - netdev->tx_queue_len = adapter->tx_queue_len; adapter->link_speed = 0; adapter->link_duplex = 0; netif_carrier_off(netdev); @@ -492,16 +405,12 @@ e1000_down(struct e1000_adapter *adapter) e1000_clean_all_tx_rings(adapter); e1000_clean_all_rx_rings(adapter); - /* Power down the PHY so no link is implied when interface is down * - * The PHY cannot be powered down if any of the following is TRUE * - * (a) WoL is enabled - * (b) AMT is active - * (c) SoL/IDER session is active */ - if (!adapter->wol && adapter->hw.mac_type >= e1000_82540 && + /* 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 && - !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN) && - !mng_mode_enabled && - !e1000_check_phy_reset_block(&adapter->hw)) { + !e1000_check_mng_mode(&adapter->hw) && + !(E1000_READ_REG(&adapter->hw, MANC) & E1000_MANC_SMBUS_EN)) { uint16_t mii_reg; e1000_read_phy_reg(&adapter->hw, PHY_CTRL, &mii_reg); mii_reg |= MII_CR_POWER_DOWN; @@ -513,8 +422,10 @@ e1000_down(struct e1000_adapter *adapter) void e1000_reset(struct e1000_adapter *adapter) { + struct net_device *netdev = adapter->netdev; uint32_t pba, manc; uint16_t fc_high_water_mark = E1000_FC_HIGH_DIFF; + uint16_t fc_low_water_mark = E1000_FC_LOW_DIFF; /* Repartition Pba for greater than 9k mtu * To take effect CTRL.RST is required. @@ -538,8 +449,15 @@ e1000_reset(struct e1000_adapter *adapter) } if((adapter->hw.mac_type != e1000_82573) && - (adapter->netdev->mtu > E1000_RXBUFFER_8192)) + (adapter->rx_buffer_len > E1000_RXBUFFER_8192)) { pba -= 8; /* allocate more FIFO for Tx */ + /* send an XOFF when there is enough space in the + * Rx FIFO to hold one extra full size Rx packet + */ + fc_high_water_mark = netdev->mtu + ENET_HEADER_SIZE + + ETHERNET_FCS_SIZE + 1; + fc_low_water_mark = fc_high_water_mark + 8; + } if(adapter->hw.mac_type == e1000_82547) { @@ -553,12 +471,10 @@ e1000_reset(struct e1000_adapter *adapter) E1000_WRITE_REG(&adapter->hw, PBA, pba); /* flow control settings */ - /* Set the FC high water mark to 90% of the FIFO size. - * Required to clear last 3 LSB */ - fc_high_water_mark = ((pba * 9216)/10) & 0xFFF8; - - adapter->hw.fc_high_water = fc_high_water_mark; - adapter->hw.fc_low_water = fc_high_water_mark - 8; + adapter->hw.fc_high_water = (pba << E1000_PBA_BYTES_SHIFT) - + fc_high_water_mark; + adapter->hw.fc_low_water = (pba << E1000_PBA_BYTES_SHIFT) - + fc_low_water_mark; adapter->hw.fc_pause_time = E1000_FC_PAUSE_TIME; adapter->hw.fc_send_xon = 1; adapter->hw.fc = adapter->hw.original_fc; @@ -601,6 +517,8 @@ 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; int i, err, pci_using_dac; @@ -794,7 +712,8 @@ e1000_probe(struct pci_dev *pdev, case e1000_82546: case e1000_82546_rev_3: case e1000_82571: - if(E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1){ + if((E1000_READ_REG(&adapter->hw, STATUS) & E1000_STATUS_FUNC_1) + && (adapter->hw.media_type == e1000_media_type_copper)) { e1000_read_eeprom(&adapter->hw, EEPROM_INIT_CONTROL3_PORT_B, 1, &eeprom_data); break; @@ -808,36 +727,25 @@ e1000_probe(struct pci_dev *pdev, if(eeprom_data & eeprom_apme_mask) adapter->wol |= E1000_WUFC_MAG; - /* print bus type/speed/width info */ - { - struct e1000_hw *hw = &adapter->hw; - DPRINTK(PROBE, INFO, "(PCI%s:%s:%s) ", - ((hw->bus_type == e1000_bus_type_pcix) ? "-X" : - (hw->bus_type == e1000_bus_type_pci_express ? " Express":"")), - ((hw->bus_speed == e1000_bus_speed_2500) ? "2.5Gb/s" : - (hw->bus_speed == e1000_bus_speed_133) ? "133MHz" : - (hw->bus_speed == e1000_bus_speed_120) ? "120MHz" : - (hw->bus_speed == e1000_bus_speed_100) ? "100MHz" : - (hw->bus_speed == e1000_bus_speed_66) ? "66MHz" : "33MHz"), - ((hw->bus_width == e1000_bus_width_64) ? "64-bit" : - (hw->bus_width == e1000_bus_width_pciex_4) ? "Width x4" : - (hw->bus_width == e1000_bus_width_pciex_1) ? "Width x1" : - "32-bit")); - } - - for (i = 0; i < 6; i++) - printk("%2.2x%c", netdev->dev_addr[i], i == 5 ? '\n' : ':'); - /* reset the hardware with the new settings */ e1000_reset(adapter); - /* If the controller is 82573 and f/w is AMT, do not set - * DRV_LOAD until the interface is up. For all other cases, - * let the f/w know that the h/w is now under the control - * of the driver. */ - if (adapter->hw.mac_type != e1000_82573 || - !e1000_check_mng_mode(&adapter->hw)) - e1000_get_hw_control(adapter); + /* 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, + swsm | E1000_SWSM_DRV_LOAD); + break; + default: + break; + } strcpy(netdev->name, "eth%d"); if((err = register_netdev(netdev))) @@ -874,7 +782,8 @@ e1000_remove(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t manc; + uint32_t ctrl_ext; + uint32_t manc, swsm; #ifdef CONFIG_E1000_NAPI int i; #endif @@ -890,13 +799,26 @@ e1000_remove(struct pci_dev *pdev) } } - /* Release control of h/w to f/w. If f/w is AMT enabled, this - * would have already happened in close and is redundant. */ - e1000_release_hw_control(adapter); + 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, + swsm & ~E1000_SWSM_DRV_LOAD); + break; + + default: + break; + } unregister_netdev(netdev); #ifdef CONFIG_E1000_NAPI - for (i = 0; i < adapter->num_rx_queues; i++) + for (i = 0; i < adapter->num_queues; i++) __dev_put(&adapter->polling_netdev[i]); #endif @@ -1001,34 +923,15 @@ e1000_sw_init(struct e1000_adapter *adapter) switch (hw->mac_type) { case e1000_82571: case e1000_82572: - /* These controllers support 2 tx queues, but with a single - * qdisc implementation, multiple tx queues aren't quite as - * interesting. If we can find a logical way of mapping - * flows to a queue, then perhaps we can up the num_tx_queue - * count back to its default. Until then, we run the risk of - * terrible performance due to SACK overload. */ - adapter->num_tx_queues = 1; - adapter->num_rx_queues = 2; + adapter->num_queues = 2; break; default: - adapter->num_tx_queues = 1; - adapter->num_rx_queues = 1; + adapter->num_queues = 1; break; } - adapter->num_rx_queues = min(adapter->num_rx_queues, num_online_cpus()); - adapter->num_tx_queues = min(adapter->num_tx_queues, num_online_cpus()); - DPRINTK(DRV, INFO, "Multiqueue Enabled: Rx Queue count = %u %s\n", - adapter->num_rx_queues, - ((adapter->num_rx_queues == 1) - ? ((num_online_cpus() > 1) - ? "(due to unsupported feature in current adapter)" - : "(due to unsupported system configuration)") - : "")); - DPRINTK(DRV, INFO, "Multiqueue Enabled: Tx Queue count = %u\n", - adapter->num_tx_queues); + adapter->num_queues = min(adapter->num_queues, num_online_cpus()); #else - adapter->num_tx_queues = 1; - adapter->num_rx_queues = 1; + adapter->num_queues = 1; #endif if (e1000_alloc_queues(adapter)) { @@ -1037,14 +940,17 @@ e1000_sw_init(struct e1000_adapter *adapter) } #ifdef CONFIG_E1000_NAPI - for (i = 0; i < adapter->num_rx_queues; i++) { + 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); } - spin_lock_init(&adapter->tx_queue_lock); +#endif + +#ifdef CONFIG_E1000_MQ + e1000_setup_queue_mapping(adapter); #endif atomic_set(&adapter->irq_sem, 1); @@ -1067,13 +973,13 @@ e1000_alloc_queues(struct e1000_adapter *adapter) { int size; - size = sizeof(struct e1000_tx_ring) * adapter->num_tx_queues; + 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_rx_queues; + size = sizeof(struct e1000_rx_ring) * adapter->num_queues; adapter->rx_ring = kmalloc(size, GFP_KERNEL); if (!adapter->rx_ring) { kfree(adapter->tx_ring); @@ -1082,7 +988,7 @@ e1000_alloc_queues(struct e1000_adapter *adapter) memset(adapter->rx_ring, 0, size); #ifdef CONFIG_E1000_NAPI - size = sizeof(struct net_device) * adapter->num_rx_queues; + size = sizeof(struct net_device) * adapter->num_queues; adapter->polling_netdev = kmalloc(size, GFP_KERNEL); if (!adapter->polling_netdev) { kfree(adapter->tx_ring); @@ -1092,14 +998,6 @@ e1000_alloc_queues(struct e1000_adapter *adapter) memset(adapter->polling_netdev, 0, size); #endif -#ifdef CONFIG_E1000_MQ - adapter->rx_sched_call_data.func = e1000_rx_schedule; - adapter->rx_sched_call_data.info = adapter->netdev; - - adapter->cpu_netdev = alloc_percpu(struct net_device *); - adapter->cpu_tx_ring = alloc_percpu(struct e1000_tx_ring *); -#endif - return E1000_SUCCESS; } @@ -1119,15 +1017,14 @@ e1000_setup_queue_mapping(struct e1000_adapter *adapter) lock_cpu_hotplug(); i = 0; for_each_online_cpu(cpu) { - *per_cpu_ptr(adapter->cpu_tx_ring, cpu) = &adapter->tx_ring[i % adapter->num_tx_queues]; + *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_rx_queues) { + if (i < adapter->num_queues) { *per_cpu_ptr(adapter->cpu_netdev, cpu) = &adapter->polling_netdev[i]; - adapter->rx_ring[i].cpu = cpu; - cpu_set(cpu, adapter->cpumask); + adapter->cpu_for_queue[i] = cpu; } else *per_cpu_ptr(adapter->cpu_netdev, cpu) = NULL; @@ -1174,12 +1071,6 @@ e1000_open(struct net_device *netdev) e1000_update_mng_vlan(adapter); } - /* If AMT is enabled, let the firmware know that the network - * interface is now open */ - if (adapter->hw.mac_type == e1000_82573 && - e1000_check_mng_mode(&adapter->hw)) - e1000_get_hw_control(adapter); - return E1000_SUCCESS; err_up: @@ -1218,13 +1109,6 @@ e1000_close(struct net_device *netdev) E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT)) { e1000_vlan_rx_kill_vid(netdev, adapter->mng_vlan_id); } - - /* If AMT is enabled, let the firmware know that the network - * interface is now closed */ - if (adapter->hw.mac_type == e1000_82573 && - e1000_check_mng_mode(&adapter->hw)) - e1000_release_hw_control(adapter); - return 0; } @@ -1345,7 +1229,7 @@ e1000_setup_all_tx_resources(struct e1000_adapter *adapter) { int i, err = 0; - for (i = 0; i < adapter->num_tx_queues; i++) { + for (i = 0; i < adapter->num_queues; i++) { err = e1000_setup_tx_resources(adapter, &adapter->tx_ring[i]); if (err) { DPRINTK(PROBE, ERR, @@ -1370,11 +1254,10 @@ e1000_configure_tx(struct e1000_adapter *adapter) uint64_t tdba; struct e1000_hw *hw = &adapter->hw; uint32_t tdlen, tctl, tipg, tarc; - uint32_t ipgr1, ipgr2; /* Setup the HW Tx Head and Tail descriptor pointers */ - switch (adapter->num_tx_queues) { + switch (adapter->num_queues) { case 2: tdba = adapter->tx_ring[1].dma; tdlen = adapter->tx_ring[1].count * @@ -1404,26 +1287,22 @@ e1000_configure_tx(struct e1000_adapter *adapter) /* Set the default values for the Tx Inter Packet Gap timer */ - 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; - switch (hw->mac_type) { case e1000_82542_rev2_0: case e1000_82542_rev2_1: tipg = DEFAULT_82542_TIPG_IPGT; - ipgr1 = DEFAULT_82542_TIPG_IPGR1; - ipgr2 = DEFAULT_82542_TIPG_IPGR2; + tipg |= DEFAULT_82542_TIPG_IPGR1 << E1000_TIPG_IPGR1_SHIFT; + tipg |= DEFAULT_82542_TIPG_IPGR2 << E1000_TIPG_IPGR2_SHIFT; break; default: - ipgr1 = DEFAULT_82543_TIPG_IPGR1; - ipgr2 = DEFAULT_82543_TIPG_IPGR2; - break; + 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; } - tipg |= ipgr1 << E1000_TIPG_IPGR1_SHIFT; - tipg |= ipgr2 << E1000_TIPG_IPGR2_SHIFT; E1000_WRITE_REG(hw, TIPG, tipg); /* Set the Tx Interrupt Delay register */ @@ -1575,8 +1454,6 @@ e1000_setup_rx_resources(struct e1000_adapter *adapter, rxdr->next_to_clean = 0; rxdr->next_to_use = 0; - rxdr->rx_skb_top = NULL; - rxdr->rx_skb_prev = NULL; return 0; } @@ -1598,7 +1475,7 @@ e1000_setup_all_rx_resources(struct e1000_adapter *adapter) { int i, err = 0; - for (i = 0; i < adapter->num_rx_queues; i++) { + for (i = 0; i < adapter->num_queues; i++) { err = e1000_setup_rx_resources(adapter, &adapter->rx_ring[i]); if (err) { DPRINTK(PROBE, ERR, @@ -1633,10 +1510,7 @@ e1000_setup_rctl(struct e1000_adapter *adapter) E1000_RCTL_LBM_NO | E1000_RCTL_RDMTS_HALF | (adapter->hw.mc_filter_type << E1000_RCTL_MO_SHIFT); - if (adapter->hw.mac_type > e1000_82543) - rctl |= E1000_RCTL_SECRC; - - if (adapter->hw.tbi_compatibility_on == 1) + if(adapter->hw.tbi_compatibility_on == 1) rctl |= E1000_RCTL_SBP; else rctl &= ~E1000_RCTL_SBP; @@ -1764,21 +1638,16 @@ e1000_configure_rx(struct e1000_adapter *adapter) } if (hw->mac_type >= e1000_82571) { - ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); /* Reset delay timers after every interrupt */ + ctrl_ext = E1000_READ_REG(hw, CTRL_EXT); ctrl_ext |= E1000_CTRL_EXT_CANC; -#ifdef CONFIG_E1000_NAPI - /* Auto-Mask interrupts upon ICR read. */ - ctrl_ext |= E1000_CTRL_EXT_IAME; -#endif E1000_WRITE_REG(hw, CTRL_EXT, ctrl_ext); - E1000_WRITE_REG(hw, IAM, ~0); 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_rx_queues) { + switch (adapter->num_queues) { #ifdef CONFIG_E1000_MQ case 2: rdba = adapter->rx_ring[1].dma; @@ -1805,7 +1674,7 @@ e1000_configure_rx(struct e1000_adapter *adapter) } #ifdef CONFIG_E1000_MQ - if (adapter->num_rx_queues > 1) { + if (adapter->num_queues > 1) { uint32_t random[10]; get_random_bytes(&random[0], 40); @@ -1815,7 +1684,7 @@ e1000_configure_rx(struct e1000_adapter *adapter) E1000_WRITE_REG(hw, RSSIM, 0); } - switch (adapter->num_rx_queues) { + switch (adapter->num_queues) { case 2: default: reta = 0x00800080; @@ -1907,7 +1776,7 @@ e1000_free_all_tx_resources(struct e1000_adapter *adapter) { int i; - for (i = 0; i < adapter->num_tx_queues; i++) + for (i = 0; i < adapter->num_queues; i++) e1000_free_tx_resources(adapter, &adapter->tx_ring[i]); } @@ -1920,10 +1789,12 @@ e1000_unmap_and_free_tx_resource(struct e1000_adapter *adapter, buffer_info->dma, buffer_info->length, PCI_DMA_TODEVICE); + buffer_info->dma = 0; } - if (buffer_info->skb) + if(buffer_info->skb) { dev_kfree_skb_any(buffer_info->skb); - memset(buffer_info, 0, sizeof(struct e1000_buffer)); + buffer_info->skb = NULL; + } } /** @@ -1972,7 +1843,7 @@ e1000_clean_all_tx_rings(struct e1000_adapter *adapter) { int i; - for (i = 0; i < adapter->num_tx_queues; i++) + for (i = 0; i < adapter->num_queues; i++) e1000_clean_tx_ring(adapter, &adapter->tx_ring[i]); } @@ -2016,7 +1887,7 @@ e1000_free_all_rx_resources(struct e1000_adapter *adapter) { int i; - for (i = 0; i < adapter->num_rx_queues; i++) + for (i = 0; i < adapter->num_queues; i++) e1000_free_rx_resources(adapter, &adapter->rx_ring[i]); } @@ -2042,6 +1913,8 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter, for(i = 0; i < rx_ring->count; i++) { buffer_info = &rx_ring->buffer_info[i]; if(buffer_info->skb) { + ps_page = &rx_ring->ps_page[i]; + ps_page_dma = &rx_ring->ps_page_dma[i]; pci_unmap_single(pdev, buffer_info->dma, buffer_info->length, @@ -2049,30 +1922,19 @@ e1000_clean_rx_ring(struct e1000_adapter *adapter, dev_kfree_skb(buffer_info->skb); buffer_info->skb = NULL; - } - ps_page = &rx_ring->ps_page[i]; - ps_page_dma = &rx_ring->ps_page_dma[i]; - for (j = 0; j < adapter->rx_ps_pages; j++) { - if (!ps_page->ps_page[j]) break; - pci_unmap_page(pdev, - ps_page_dma->ps_page_dma[j], - PAGE_SIZE, PCI_DMA_FROMDEVICE); - ps_page_dma->ps_page_dma[j] = 0; - put_page(ps_page->ps_page[j]); - ps_page->ps_page[j] = NULL; - } - } - - /* there also may be some cached data in our adapter */ - if (rx_ring->rx_skb_top) { - dev_kfree_skb(rx_ring->rx_skb_top); - /* rx_skb_prev will be wiped out by rx_skb_top */ - rx_ring->rx_skb_top = NULL; - rx_ring->rx_skb_prev = NULL; + 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], + PAGE_SIZE, PCI_DMA_FROMDEVICE); + ps_page_dma->ps_page_dma[j] = 0; + put_page(ps_page->ps_page[j]); + ps_page->ps_page[j] = NULL; + } + } } - size = sizeof(struct e1000_buffer) * rx_ring->count; memset(rx_ring->buffer_info, 0, size); size = sizeof(struct e1000_ps_page) * rx_ring->count; @@ -2101,7 +1963,7 @@ e1000_clean_all_rx_rings(struct e1000_adapter *adapter) { int i; - for (i = 0; i < adapter->num_rx_queues; i++) + for (i = 0; i < adapter->num_queues; i++) e1000_clean_rx_ring(adapter, &adapter->rx_ring[i]); } @@ -2143,9 +2005,7 @@ e1000_leave_82542_rst(struct e1000_adapter *adapter) if(netif_running(netdev)) { e1000_configure_rx(adapter); - /* No need to loop, because 82542 supports only 1 queue */ - struct e1000_rx_ring *ring = &adapter->rx_ring[0]; - adapter->alloc_rx_buf(adapter, ring, E1000_DESC_UNUSED(ring)); + e1000_alloc_rx_buffers(adapter, &adapter->rx_ring[0]); } } @@ -2344,7 +2204,7 @@ static void e1000_watchdog_task(struct e1000_adapter *adapter) { struct net_device *netdev = adapter->netdev; - struct e1000_tx_ring *txdr = adapter->tx_ring; + struct e1000_tx_ring *txdr = &adapter->tx_ring[0]; uint32_t link; e1000_check_for_link(&adapter->hw); @@ -2371,21 +2231,6 @@ e1000_watchdog_task(struct e1000_adapter *adapter) adapter->link_duplex == FULL_DUPLEX ? "Full Duplex" : "Half Duplex"); - /* tweak tx_queue_len according to speed/duplex */ - netdev->tx_queue_len = adapter->tx_queue_len; - adapter->tx_timeout_factor = 1; - if (adapter->link_duplex == HALF_DUPLEX) { - switch (adapter->link_speed) { - case SPEED_10: - netdev->tx_queue_len = 10; - adapter->tx_timeout_factor = 8; - break; - case SPEED_100: - netdev->tx_queue_len = 100; - break; - } - } - netif_carrier_on(netdev); netif_wake_queue(netdev); mod_timer(&adapter->phy_info_timer, jiffies + 2 * HZ); @@ -2418,10 +2263,7 @@ e1000_watchdog_task(struct e1000_adapter *adapter) e1000_update_adaptive(&adapter->hw); -#ifdef CONFIG_E1000_MQ - txdr = *per_cpu_ptr(adapter->cpu_tx_ring, smp_processor_id()); -#endif - if (!netif_carrier_ok(netdev)) { + 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 @@ -2472,7 +2314,6 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, { #ifdef NETIF_F_TSO struct e1000_context_desc *context_desc; - struct e1000_buffer *buffer_info; unsigned int i; uint32_t cmd_length = 0; uint16_t ipcse = 0, tucse, mss; @@ -2522,7 +2363,6 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, i = tx_ring->next_to_use; context_desc = E1000_CONTEXT_DESC(*tx_ring, i); - buffer_info = &tx_ring->buffer_info[i]; context_desc->lower_setup.ip_fields.ipcss = ipcss; context_desc->lower_setup.ip_fields.ipcso = ipcso; @@ -2534,16 +2374,14 @@ e1000_tso(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, context_desc->tcp_seg_setup.fields.hdr_len = hdr_len; context_desc->cmd_and_length = cpu_to_le32(cmd_length); - buffer_info->time_stamp = jiffies; - if (++i == tx_ring->count) i = 0; tx_ring->next_to_use = i; - return TRUE; + return 1; } #endif - return FALSE; + return 0; } static inline boolean_t @@ -2551,7 +2389,6 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, struct sk_buff *skb) { struct e1000_context_desc *context_desc; - struct e1000_buffer *buffer_info; unsigned int i; uint8_t css; @@ -2559,7 +2396,6 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, css = skb->h.raw - skb->data; i = tx_ring->next_to_use; - buffer_info = &tx_ring->buffer_info[i]; context_desc = E1000_CONTEXT_DESC(*tx_ring, i); context_desc->upper_setup.tcp_fields.tucss = css; @@ -2568,8 +2404,6 @@ e1000_tx_csum(struct e1000_adapter *adapter, struct e1000_tx_ring *tx_ring, context_desc->tcp_seg_setup.data = 0; context_desc->cmd_and_length = cpu_to_le32(E1000_TXD_CMD_DEXT); - buffer_info->time_stamp = jiffies; - if (unlikely(++i == tx_ring->count)) i = 0; tx_ring->next_to_use = i; @@ -2854,30 +2688,11 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) * overrun the FIFO, adjust the max buffer len if mss * drops. */ if(mss) { - uint8_t hdr_len; max_per_txd = min(mss << 2, max_per_txd); max_txd_pwr = fls(max_per_txd) - 1; - - /* TSO Workaround for 82571/2 Controllers -- if skb->data - * points to just header, pull a few bytes of payload from - * frags into skb->data */ - 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; - } - len = skb->len - skb->data_len; - } } if((mss) || (skb->ip_summed == CHECKSUM_HW)) - /* reserve a descriptor for the offload context */ count++; count++; #else @@ -2911,6 +2726,27 @@ e1000_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if(adapter->pcix_82544) count += nr_frags; +#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); @@ -2997,7 +2833,6 @@ e1000_tx_timeout_task(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); - adapter->tx_timeout_count++; e1000_down(adapter); e1000_up(adapter); } @@ -3015,7 +2850,7 @@ e1000_get_stats(struct net_device *netdev) { struct e1000_adapter *adapter = netdev_priv(netdev); - /* only return the current stats */ + e1000_update_stats(adapter); return &adapter->net_stats; } @@ -3036,50 +2871,49 @@ e1000_change_mtu(struct net_device *netdev, int new_mtu) if((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || (max_frame > MAX_JUMBO_FRAME_SIZE)) { DPRINTK(PROBE, ERR, "Invalid MTU setting\n"); - return -EINVAL; + return -EINVAL; } - /* Adapter-specific max frame size limits. */ - switch (adapter->hw.mac_type) { - case e1000_82542_rev2_0: - case e1000_82542_rev2_1: - case e1000_82573: - if (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE) { - DPRINTK(PROBE, ERR, "Jumbo Frames not supported.\n"); - return -EINVAL; - } - break; - case e1000_82571: - case e1000_82572: #define MAX_STD_JUMBO_FRAME_SIZE 9234 - if (max_frame > MAX_STD_JUMBO_FRAME_SIZE) { - DPRINTK(PROBE, ERR, "MTU > 9216 not supported.\n"); - return -EINVAL; - } - break; - default: - /* Capable of supporting up to MAX_JUMBO_FRAME_SIZE limit. */ - break; + /* might want this to be bigger enum check... */ + /* 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"); + return -EINVAL; } - /* since the driver code now supports splitting a packet across - * multiple descriptors, most of the fifo related limitations on - * jumbo frame traffic have gone away. - * simply use 2k descriptors for everything. - * - * NOTE: dev_alloc_skb reserves 16 bytes, and typically NET_IP_ALIGN - * means we reserve 2 more, this pushes us to allocate from the next - * larger slab size - * i.e. RXBUFFER_2048 --> size-4096 slab */ - - /* recent hardware supports 1KB granularity */ - if (adapter->hw.mac_type > e1000_82547_rev_2) { - adapter->rx_buffer_len = - ((max_frame < E1000_RXBUFFER_2048) ? - max_frame : E1000_RXBUFFER_2048); + if(adapter->hw.mac_type > e1000_82547_rev_2) { + adapter->rx_buffer_len = max_frame; E1000_ROUNDUP(adapter->rx_buffer_len, 1024); - } else - adapter->rx_buffer_len = E1000_RXBUFFER_2048; + } else { + if(unlikely((adapter->hw.mac_type < e1000_82543) && + (max_frame > MAXIMUM_ETHERNET_FRAME_SIZE))) { + DPRINTK(PROBE, ERR, "Jumbo Frames not supported " + "on 82542\n"); + return -EINVAL; + + } else { + if(max_frame <= E1000_RXBUFFER_2048) { + adapter->rx_buffer_len = E1000_RXBUFFER_2048; + } else if(max_frame <= E1000_RXBUFFER_4096) { + adapter->rx_buffer_len = E1000_RXBUFFER_4096; + } else if(max_frame <= E1000_RXBUFFER_8192) { + adapter->rx_buffer_len = E1000_RXBUFFER_8192; + } else if(max_frame <= E1000_RXBUFFER_16384) { + adapter->rx_buffer_len = E1000_RXBUFFER_16384; + } + } + } netdev->mtu = new_mtu; @@ -3203,11 +3037,12 @@ e1000_update_stats(struct e1000_adapter *adapter) adapter->net_stats.rx_errors = adapter->stats.rxerrc + adapter->stats.crcerrs + adapter->stats.algnerrc + - adapter->stats.rlec + adapter->stats.cexterr; - adapter->net_stats.rx_dropped = 0; + adapter->stats.rlec + adapter->stats.mpc + + adapter->stats.cexterr; adapter->net_stats.rx_length_errors = adapter->stats.rlec; adapter->net_stats.rx_crc_errors = adapter->stats.crcerrs; adapter->net_stats.rx_frame_errors = adapter->stats.algnerrc; + adapter->net_stats.rx_fifo_errors = adapter->stats.mpc; adapter->net_stats.rx_missed_errors = adapter->stats.mpc; /* Tx Errors */ @@ -3275,24 +3110,12 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) 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 +#if defined(CONFIG_E1000_NAPI) && defined(CONFIG_E1000_MQ) || !defined(CONFIG_E1000_NAPI) int i; -#else - /* Interrupt Auto-Mask...upon reading ICR, - * interrupts are masked. No need for the - * IMC write, but it does mean we should - * account for it ASAP. */ - if (likely(hw->mac_type >= e1000_82571)) - atomic_inc(&adapter->irq_sem); #endif - if (unlikely(!icr)) { -#ifdef CONFIG_E1000_NAPI - if (hw->mac_type >= e1000_82571) - e1000_irq_enable(adapter); -#endif + if(unlikely(!icr)) return IRQ_NONE; /* Not our interrupt */ - } if(unlikely(icr & (E1000_ICR_RXSEQ | E1000_ICR_LSC))) { hw->get_link_status = 1; @@ -3300,19 +3123,19 @@ e1000_intr(int irq, void *data, struct pt_regs *regs) } #ifdef CONFIG_E1000_NAPI - if (unlikely(hw->mac_type < e1000_82571)) { - atomic_inc(&adapter->irq_sem); - E1000_WRITE_REG(hw, IMC, ~0); - E1000_WRITE_FLUSH(hw); - } + 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) { - /* We must setup the cpumask once count == 0 since - * each cpu bit is cleared when the work is done. */ - adapter->rx_sched_call_data.cpumask = adapter->cpumask; - atomic_add(adapter->num_rx_queues - 1, &adapter->irq_sem); - atomic_set(&adapter->rx_sched_call_data.count, - adapter->num_rx_queues); + 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)); @@ -3364,7 +3187,7 @@ e1000_clean(struct net_device *poll_dev, int *budget) { struct e1000_adapter *adapter; int work_to_do = min(*budget, poll_dev->quota); - int tx_cleaned = 0, i = 0, work_done = 0; + int tx_cleaned, i = 0, work_done = 0; /* Must NOT use netdev_priv macro here. */ adapter = poll_dev->priv; @@ -3375,23 +3198,11 @@ e1000_clean(struct net_device *poll_dev, int *budget) while (poll_dev != &adapter->polling_netdev[i]) { i++; - if (unlikely(i == adapter->num_rx_queues)) + if (unlikely(i == adapter->num_queues)) BUG(); } - if (likely(adapter->num_tx_queues == 1)) { - /* e1000_clean is called per-cpu. This lock protects - * tx_ring[0] from being cleaned by multiple cpus - * simultaneously. A failure obtaining the lock means - * tx_ring[0] is currently being cleaned anyway. */ - if (spin_trylock(&adapter->tx_queue_lock)) { - tx_cleaned = e1000_clean_tx_irq(adapter, - &adapter->tx_ring[0]); - spin_unlock(&adapter->tx_queue_lock); - } - } else - tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]); - + tx_cleaned = e1000_clean_tx_irq(adapter, &adapter->tx_ring[i]); adapter->clean_rx(adapter, &adapter->rx_ring[i], &work_done, work_to_do); @@ -3436,19 +3247,17 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, buffer_info = &tx_ring->buffer_info[i]; cleaned = (i == eop); -#ifdef CONFIG_E1000_MQ - tx_ring->tx_stats.bytes += buffer_info->length; -#endif e1000_unmap_and_free_tx_resource(adapter, buffer_info); - memset(tx_desc, 0, sizeof(struct e1000_tx_desc)); + + tx_desc->buffer_addr = 0; + tx_desc->lower.data = 0; + tx_desc->upper.data = 0; if(unlikely(++i == tx_ring->count)) i = 0; } -#ifdef CONFIG_E1000_MQ - tx_ring->tx_stats.packets++; -#endif - + tx_ring->pkt++; + eop = tx_ring->buffer_info[i].next_to_watch; eop_desc = E1000_TX_DESC(*tx_ring, eop); } @@ -3467,31 +3276,32 @@ e1000_clean_tx_irq(struct e1000_adapter *adapter, /* 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; - if (tx_ring->buffer_info[eop].dma && - time_after(jiffies, tx_ring->buffer_info[eop].time_stamp + - adapter->tx_timeout_factor * HZ) + if (tx_ring->buffer_info[i].dma && + time_after(jiffies, tx_ring->buffer_info[i].time_stamp + HZ) && !(E1000_READ_REG(&adapter->hw, STATUS) & - E1000_STATUS_TXOFF)) { + E1000_STATUS_TXOFF)) { /* detected Tx unit hang */ + i = tx_ring->next_to_clean; + eop = tx_ring->buffer_info[i].next_to_watch; + eop_desc = E1000_TX_DESC(*tx_ring, eop); DPRINTK(DRV, ERR, "Detected Tx Unit Hang\n" - " Tx Queue <%lu>\n" " TDH <%x>\n" " TDT <%x>\n" " next_to_use <%x>\n" " next_to_clean <%x>\n" "buffer_info[next_to_clean]\n" + " dma <%llx>\n" " time_stamp <%lx>\n" " next_to_watch <%x>\n" " jiffies <%lx>\n" " next_to_watch.status <%x>\n", - (unsigned long)((tx_ring - adapter->tx_ring) / - sizeof(struct e1000_tx_ring)), readl(adapter->hw.hw_addr + tx_ring->tdh), readl(adapter->hw.hw_addr + tx_ring->tdt), tx_ring->next_to_use, - tx_ring->next_to_clean, - tx_ring->buffer_info[eop].time_stamp, + i, + (unsigned long long)tx_ring->buffer_info[i].dma, + tx_ring->buffer_info[i].time_stamp, eop, jiffies, eop_desc->upper.fields.status); @@ -3576,23 +3386,20 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, uint32_t length; uint8_t last_byte; unsigned int i; - int cleaned_count = 0; - boolean_t cleaned = FALSE, multi_descriptor = FALSE; + boolean_t cleaned = FALSE; i = rx_ring->next_to_clean; rx_desc = E1000_RX_DESC(*rx_ring, i); while(rx_desc->status & E1000_RXD_STAT_DD) { buffer_info = &rx_ring->buffer_info[i]; - u8 status; #ifdef CONFIG_E1000_NAPI if(*work_done >= work_to_do) break; (*work_done)++; #endif - status = rx_desc->status; cleaned = TRUE; - cleaned_count++; + pci_unmap_single(pdev, buffer_info->dma, buffer_info->length, @@ -3626,40 +3433,18 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, } } - /* code added for copybreak, this should improve - * performance for small packets with large amounts - * of reassembly being done in the stack */ -#define E1000_CB_LENGTH 256 - if ((length < E1000_CB_LENGTH) && - !rx_ring->rx_skb_top && - /* or maybe (status & E1000_RXD_STAT_EOP) && */ - !multi_descriptor) { - struct sk_buff *new_skb = - dev_alloc_skb(length + NET_IP_ALIGN); - if (new_skb) { - skb_reserve(new_skb, NET_IP_ALIGN); - new_skb->dev = netdev; - memcpy(new_skb->data - NET_IP_ALIGN, - skb->data - NET_IP_ALIGN, - length + NET_IP_ALIGN); - /* save the skb in buffer_info as good */ - buffer_info->skb = skb; - skb = new_skb; - skb_put(skb, length); - } - } - - /* end copybreak code */ + /* Good Receive */ + skb_put(skb, length - ETHERNET_FCS_SIZE); /* Receive Checksum Offload */ e1000_rx_checksum(adapter, - (uint32_t)(status) | + (uint32_t)(rx_desc->status) | ((uint32_t)(rx_desc->errors) << 24), rx_desc->csum, skb); skb->protocol = eth_type_trans(skb, netdev); #ifdef CONFIG_E1000_NAPI if(unlikely(adapter->vlgrp && - (status & E1000_RXD_STAT_VP))) { + (rx_desc->status & E1000_RXD_STAT_VP))) { vlan_hwaccel_receive_skb(skb, adapter->vlgrp, le16_to_cpu(rx_desc->special) & E1000_RXD_SPC_VLAN_MASK); @@ -3677,26 +3462,17 @@ e1000_clean_rx_irq(struct e1000_adapter *adapter, } #endif /* CONFIG_E1000_NAPI */ netdev->last_rx = jiffies; -#ifdef CONFIG_E1000_MQ - rx_ring->rx_stats.packets++; - rx_ring->rx_stats.bytes += length; -#endif + rx_ring->pkt++; next_desc: rx_desc->status = 0; + buffer_info->skb = NULL; + if(unlikely(++i == rx_ring->count)) i = 0; - /* return some buffers to hardware, one at a time is too slow */ - if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { - adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count); - cleaned_count = 0; - } - + rx_desc = E1000_RX_DESC(*rx_ring, i); } rx_ring->next_to_clean = i; - - cleaned_count = E1000_DESC_UNUSED(rx_ring); - if (cleaned_count) - adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count); + adapter->alloc_rx_buf(adapter, rx_ring); return cleaned; } @@ -3725,7 +3501,6 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, struct sk_buff *skb; unsigned int i, j; uint32_t length, staterr; - int cleaned_count = 0; boolean_t cleaned = FALSE; i = rx_ring->next_to_clean; @@ -3742,7 +3517,6 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, (*work_done)++; #endif cleaned = TRUE; - cleaned_count++; pci_unmap_single(pdev, buffer_info->dma, buffer_info->length, PCI_DMA_FROMDEVICE); @@ -3819,28 +3593,18 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, } #endif /* CONFIG_E1000_NAPI */ netdev->last_rx = jiffies; -#ifdef CONFIG_E1000_MQ - rx_ring->rx_stats.packets++; - rx_ring->rx_stats.bytes += length; -#endif + rx_ring->pkt++; next_desc: rx_desc->wb.middle.status_error &= ~0xFF; buffer_info->skb = NULL; + if(unlikely(++i == rx_ring->count)) i = 0; - /* return some buffers to hardware, one at a time is too slow */ - if (unlikely(cleaned_count >= E1000_RX_BUFFER_WRITE)) { - adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count); - cleaned_count = 0; - } - + rx_desc = E1000_RX_DESC_PS(*rx_ring, i); staterr = le32_to_cpu(rx_desc->wb.middle.status_error); } rx_ring->next_to_clean = i; - - cleaned_count = E1000_DESC_UNUSED(rx_ring); - if (cleaned_count) - adapter->alloc_rx_buf(adapter, rx_ring, cleaned_count); + adapter->alloc_rx_buf(adapter, rx_ring); return cleaned; } @@ -3852,8 +3616,7 @@ e1000_clean_rx_irq_ps(struct e1000_adapter *adapter, static void e1000_alloc_rx_buffers(struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int cleaned_count) + struct e1000_rx_ring *rx_ring) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -3866,18 +3629,11 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, i = rx_ring->next_to_use; buffer_info = &rx_ring->buffer_info[i]; - while (cleaned_count--) { - if (!(skb = buffer_info->skb)) - skb = dev_alloc_skb(bufsz); - else { - skb_trim(skb, 0); - goto map_skb; - } - + while(!buffer_info->skb) { + skb = dev_alloc_skb(bufsz); if(unlikely(!skb)) { /* Better luck next round */ - adapter->alloc_rx_buff_failed++; break; } @@ -3914,7 +3670,6 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, buffer_info->skb = skb; buffer_info->length = adapter->rx_buffer_len; -map_skb: buffer_info->dma = pci_map_single(pdev, skb->data, adapter->rx_buffer_len, @@ -3963,8 +3718,7 @@ e1000_alloc_rx_buffers(struct e1000_adapter *adapter, static void e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, - struct e1000_rx_ring *rx_ring, - int cleaned_count) + struct e1000_rx_ring *rx_ring) { struct net_device *netdev = adapter->netdev; struct pci_dev *pdev = adapter->pdev; @@ -3980,7 +3734,7 @@ e1000_alloc_rx_buffers_ps(struct e1000_adapter *adapter, ps_page = &rx_ring->ps_page[i]; ps_page_dma = &rx_ring->ps_page_dma[i]; - while (cleaned_count--) { + while(!buffer_info->skb) { rx_desc = E1000_RX_DESC_PS(*rx_ring, i); for(j = 0; j < PS_PAGE_BUFFERS; j++) { @@ -4352,12 +4106,8 @@ e1000_vlan_rx_kill_vid(struct net_device *netdev, uint16_t vid) if((adapter->hw.mng_cookie.status & E1000_MNG_DHCP_COOKIE_STATUS_VLAN_SUPPORT) && - (vid == adapter->mng_vlan_id)) { - /* release control to f/w */ - e1000_release_hw_control(adapter); + (vid == adapter->mng_vlan_id)) return; - } - /* remove VID from filter table */ index = (vid >> 5) & 0x7F; vfta = E1000_READ_REG_ARRAY(&adapter->hw, VFTA, index); @@ -4423,9 +4173,8 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - uint32_t ctrl, ctrl_ext, rctl, manc, status; + uint32_t ctrl, ctrl_ext, rctl, manc, status, swsm; uint32_t wufc = adapter->wol; - int retval = 0; netif_device_detach(netdev); @@ -4471,21 +4220,13 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) E1000_WRITE_REG(&adapter->hw, WUC, E1000_WUC_PME_EN); E1000_WRITE_REG(&adapter->hw, WUFC, wufc); - retval = pci_enable_wake(pdev, PCI_D3hot, 1); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); - retval = pci_enable_wake(pdev, PCI_D3cold, 1); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); + pci_enable_wake(pdev, 3, 1); + pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */ } else { E1000_WRITE_REG(&adapter->hw, WUC, 0); E1000_WRITE_REG(&adapter->hw, WUFC, 0); - retval = pci_enable_wake(pdev, PCI_D3hot, 0); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); - retval = pci_enable_wake(pdev, PCI_D3cold, 0); /* 4 == D3 cold */ - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); + pci_enable_wake(pdev, 3, 0); + pci_enable_wake(pdev, 4, 0); /* 4 == D3 cold */ } pci_save_state(pdev); @@ -4496,24 +4237,29 @@ e1000_suspend(struct pci_dev *pdev, pm_message_t state) if(manc & E1000_MANC_SMBUS_EN) { manc |= E1000_MANC_ARP_EN; E1000_WRITE_REG(&adapter->hw, MANC, manc); - retval = pci_enable_wake(pdev, PCI_D3hot, 1); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); - retval = pci_enable_wake(pdev, PCI_D3cold, 1); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); + pci_enable_wake(pdev, 3, 1); + pci_enable_wake(pdev, 4, 1); /* 4 == D3 cold */ } } - /* Release control of h/w to f/w. If f/w is AMT enabled, this - * would have already happened in close and is redundant. */ - e1000_release_hw_control(adapter); + 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, + swsm & ~E1000_SWSM_DRV_LOAD); + break; + default: + break; + } pci_disable_device(pdev); - - retval = pci_set_power_state(pdev, pci_choose_state(pdev, state)); - if (retval) - DPRINTK(PROBE, ERR, "Error in setting power state\n"); + pci_set_power_state(pdev, pci_choose_state(pdev, state)); return 0; } @@ -4523,21 +4269,16 @@ e1000_resume(struct pci_dev *pdev) { struct net_device *netdev = pci_get_drvdata(pdev); struct e1000_adapter *adapter = netdev_priv(netdev); - int retval; - uint32_t manc, ret_val; + uint32_t manc, ret_val, swsm; + uint32_t ctrl_ext; - retval = pci_set_power_state(pdev, PCI_D0); - if (retval) - DPRINTK(PROBE, ERR, "Error in setting power state\n"); + pci_set_power_state(pdev, PCI_D0); + pci_restore_state(pdev); ret_val = pci_enable_device(pdev); pci_set_master(pdev); - retval = pci_enable_wake(pdev, PCI_D3hot, 0); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 wake\n"); - retval = pci_enable_wake(pdev, PCI_D3cold, 0); - if (retval) - DPRINTK(PROBE, ERR, "Error enabling D3 cold wake\n"); + pci_enable_wake(pdev, PCI_D3hot, 0); + pci_enable_wake(pdev, PCI_D3cold, 0); e1000_reset(adapter); E1000_WRITE_REG(&adapter->hw, WUS, ~0); @@ -4554,13 +4295,21 @@ e1000_resume(struct pci_dev *pdev) E1000_WRITE_REG(&adapter->hw, MANC, manc); } - /* If the controller is 82573 and f/w is AMT, do not set - * DRV_LOAD until the interface is up. For all other cases, - * let the f/w know that the h/w is now under the control - * of the driver. */ - if (adapter->hw.mac_type != e1000_82573 || - !e1000_check_mng_mode(&adapter->hw)) - e1000_get_hw_control(adapter); + 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, + swsm | E1000_SWSM_DRV_LOAD); + break; + default: + break; + } return 0; } @@ -4578,9 +4327,6 @@ e1000_netpoll(struct net_device *netdev) disable_irq(adapter->pdev->irq); e1000_intr(adapter->pdev->irq, netdev, NULL); e1000_clean_tx_irq(adapter, adapter->tx_ring); -#ifndef CONFIG_E1000_NAPI - adapter->clean_rx(adapter, adapter->rx_ring); -#endif enable_irq(adapter->pdev->irq); } #endif diff --git a/trunk/drivers/net/e1000/e1000_param.c b/trunk/drivers/net/e1000/e1000_param.c index 0a7918c62557..ccbbe5ad8e0f 100644 --- a/trunk/drivers/net/e1000/e1000_param.c +++ b/trunk/drivers/net/e1000/e1000_param.c @@ -177,7 +177,7 @@ E1000_PARAM(RxAbsIntDelay, "Receive Absolute Interrupt Delay"); * * Valid Range: 100-100000 (0=off, 1=dynamic) * - * Default Value: 8000 + * Default Value: 1 */ E1000_PARAM(InterruptThrottleRate, "Interrupt Throttling Rate"); @@ -320,7 +320,7 @@ e1000_check_options(struct e1000_adapter *adapter) } else { tx_ring->count = opt.def; } - for (i = 0; i < adapter->num_tx_queues; i++) + for (i = 0; i < adapter->num_queues; i++) tx_ring[i].count = tx_ring->count; } { /* Receive Descriptor Count */ @@ -346,7 +346,7 @@ e1000_check_options(struct e1000_adapter *adapter) } else { rx_ring->count = opt.def; } - for (i = 0; i < adapter->num_rx_queues; i++) + for (i = 0; i < adapter->num_queues; i++) rx_ring[i].count = rx_ring->count; } { /* Checksum Offload Enable/Disable */ @@ -388,7 +388,7 @@ e1000_check_options(struct e1000_adapter *adapter) e1000_validate_option(&fc, &opt, adapter); adapter->hw.fc = adapter->hw.original_fc = fc; } else { - adapter->hw.fc = adapter->hw.original_fc = opt.def; + adapter->hw.fc = opt.def; } } { /* Transmit Interrupt Delay */ @@ -584,12 +584,6 @@ e1000_check_copper_options(struct e1000_adapter *adapter) .p = dplx_list }} }; - if (e1000_check_phy_reset_block(&adapter->hw)) { - DPRINTK(PROBE, INFO, - "Link active due to SoL/IDER Session. " - "Speed/Duplex/AutoNeg parameter ignored.\n"); - return; - } if (num_Duplex > bd) { dplx = Duplex[bd]; e1000_validate_option(&dplx, &opt, adapter); diff --git a/trunk/drivers/net/mv643xx_eth.c b/trunk/drivers/net/mv643xx_eth.c index 40ae36b20c9d..22c3a37bba5a 100644 --- a/trunk/drivers/net/mv643xx_eth.c +++ b/trunk/drivers/net/mv643xx_eth.c @@ -35,8 +35,6 @@ #include #include #include -#include -#include #include #include @@ -57,15 +55,13 @@ /* Constants */ #define VLAN_HLEN 4 #define FCS_LEN 4 -#define DMA_ALIGN 8 /* hw requires 8-byte alignment */ -#define HW_IP_ALIGN 2 /* hw aligns IP header */ -#define WRAP HW_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN +#define WRAP NET_IP_ALIGN + ETH_HLEN + VLAN_HLEN + FCS_LEN #define RX_SKB_SIZE ((dev->mtu + WRAP + 7) & ~0x7) -#define INT_UNMASK_ALL 0x0007ffff -#define INT_UNMASK_ALL_EXT 0x0011ffff -#define INT_MASK_ALL 0x00000000 -#define INT_MASK_ALL_EXT 0x00000000 +#define INT_CAUSE_UNMASK_ALL 0x0007ffff +#define INT_CAUSE_UNMASK_ALL_EXT 0x0011ffff +#define INT_CAUSE_MASK_ALL 0x00000000 +#define INT_CAUSE_MASK_ALL_EXT 0x00000000 #define INT_CAUSE_CHECK_BITS INT_CAUSE_UNMASK_ALL #define INT_CAUSE_CHECK_BITS_EXT INT_CAUSE_UNMASK_ALL_EXT @@ -82,9 +78,8 @@ static int eth_port_link_is_up(unsigned int eth_port_num); static void eth_port_uc_addr_get(struct net_device *dev, unsigned char *MacAddr); -static void eth_port_set_multicast_list(struct net_device *); -static int mv643xx_eth_open(struct net_device *); -static int mv643xx_eth_stop(struct net_device *); +static int mv643xx_eth_real_open(struct net_device *); +static int mv643xx_eth_real_stop(struct net_device *); static int mv643xx_eth_change_mtu(struct net_device *, int); static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *); static void eth_port_init_mac_tables(unsigned int eth_port_num); @@ -129,8 +124,15 @@ static inline void mv_write(int offset, u32 data) */ static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) { - if ((new_mtu > 9500) || (new_mtu < 64)) + struct mv643xx_private *mp = netdev_priv(dev); + unsigned long flags; + + spin_lock_irqsave(&mp->lock, flags); + + if ((new_mtu > 9500) || (new_mtu < 64)) { + spin_unlock_irqrestore(&mp->lock, flags); return -EINVAL; + } dev->mtu = new_mtu; /* @@ -140,13 +142,17 @@ static int mv643xx_eth_change_mtu(struct net_device *dev, int new_mtu) * to memory is full, which might fail the open function. */ if (netif_running(dev)) { - mv643xx_eth_stop(dev); - if (mv643xx_eth_open(dev)) + if (mv643xx_eth_real_stop(dev)) + printk(KERN_ERR + "%s: Fatal error on stopping device\n", + dev->name); + if (mv643xx_eth_real_open(dev)) printk(KERN_ERR "%s: Fatal error on opening device\n", dev->name); } + spin_unlock_irqrestore(&mp->lock, flags); return 0; } @@ -164,19 +170,15 @@ static void mv643xx_eth_rx_task(void *data) struct mv643xx_private *mp = netdev_priv(dev); struct pkt_info pkt_info; struct sk_buff *skb; - int unaligned; if (test_and_set_bit(0, &mp->rx_task_busy)) panic("%s: Error in test_set_bit / clear_bit", dev->name); while (mp->rx_ring_skbs < (mp->rx_ring_size - 5)) { - skb = dev_alloc_skb(RX_SKB_SIZE + DMA_ALIGN); + skb = dev_alloc_skb(RX_SKB_SIZE); if (!skb) break; mp->rx_ring_skbs++; - unaligned = (u32)skb->data & (DMA_ALIGN - 1); - if (unaligned) - skb_reserve(skb, DMA_ALIGN - unaligned); pkt_info.cmd_sts = ETH_RX_ENABLE_INTERRUPT; pkt_info.byte_cnt = RX_SKB_SIZE; pkt_info.buf_ptr = dma_map_single(NULL, skb->data, RX_SKB_SIZE, @@ -187,7 +189,7 @@ static void mv643xx_eth_rx_task(void *data) "%s: Error allocating RX Ring\n", dev->name); break; } - skb_reserve(skb, HW_IP_ALIGN); + skb_reserve(skb, 2); } clear_bit(0, &mp->rx_task_busy); /* @@ -205,7 +207,7 @@ static void mv643xx_eth_rx_task(void *data) else { /* Return interrupts */ mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(mp->port_num), - INT_UNMASK_ALL); + INT_CAUSE_UNMASK_ALL); } #endif } @@ -265,8 +267,6 @@ static void mv643xx_eth_set_rx_mode(struct net_device *dev) mp->port_config &= ~(u32) MV643XX_ETH_UNICAST_PROMISCUOUS_MODE; mv_write(MV643XX_ETH_PORT_CONFIG_REG(mp->port_num), mp->port_config); - - eth_port_set_multicast_list(dev); } /* @@ -342,6 +342,8 @@ static int mv643xx_eth_free_tx_queue(struct net_device *dev, if (!(eth_int_cause_ext & (BIT0 | BIT8))) return released; + spin_lock(&mp->lock); + /* Check only queue 0 */ while (eth_tx_return_desc(mp, &pkt_info) == ETH_OK) { if (pkt_info.cmd_sts & BIT0) { @@ -349,21 +351,31 @@ static int mv643xx_eth_free_tx_queue(struct net_device *dev, stats->tx_errors++; } - if (pkt_info.cmd_sts & ETH_TX_FIRST_DESC) - dma_unmap_single(NULL, pkt_info.buf_ptr, - pkt_info.byte_cnt, - DMA_TO_DEVICE); - else - dma_unmap_page(NULL, pkt_info.buf_ptr, - pkt_info.byte_cnt, - DMA_TO_DEVICE); - + /* + * If return_info is different than 0, release the skb. + * The case where return_info is not 0 is only in case + * when transmitted a scatter/gather packet, where only + * last skb releases the whole chain. + */ if (pkt_info.return_info) { + if (skb_shinfo(pkt_info.return_info)->nr_frags) + dma_unmap_page(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, + DMA_TO_DEVICE); + else + dma_unmap_single(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, + DMA_TO_DEVICE); + dev_kfree_skb_irq(pkt_info.return_info); released = 0; - } + } else + dma_unmap_page(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, DMA_TO_DEVICE); } + spin_unlock(&mp->lock); + return released; } @@ -470,12 +482,12 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, /* Read interrupt cause registers */ eth_int_cause = mv_read(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num)) & - INT_UNMASK_ALL; + INT_CAUSE_UNMASK_ALL; if (eth_int_cause & BIT1) eth_int_cause_ext = mv_read( MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num)) & - INT_UNMASK_ALL_EXT; + INT_CAUSE_UNMASK_ALL_EXT; #ifdef MV643XX_NAPI if (!(eth_int_cause & 0x0007fffd)) { @@ -500,10 +512,9 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, } else { if (netif_rx_schedule_prep(dev)) { /* Mask all the interrupts */ - mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), - INT_MASK_ALL); - /* wait for previous write to complete */ - mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0); + mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG + (port_num), 0); __netif_rx_schedule(dev); } #else @@ -516,12 +527,9 @@ static irqreturn_t mv643xx_eth_int_handler(int irq, void *dev_id, * with skb's. */ #ifdef MV643XX_RX_QUEUE_FILL_ON_TASK - /* Mask all interrupts on ethernet port */ + /* Unmask all interrupts on ethernet port */ mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), - INT_MASK_ALL); - /* wait for previous write to take effect */ - mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); - + INT_CAUSE_MASK_ALL); queue_task(&mp->rx_task, &tq_immediate); mark_bh(IMMEDIATE_BH); #else @@ -627,6 +635,56 @@ static unsigned int eth_port_set_tx_coal(unsigned int eth_port_num, return coal; } +/* + * mv643xx_eth_open + * + * This function is called when openning the network device. The function + * should initialize all the hardware, initialize cyclic Rx/Tx + * descriptors chain and buffers and allocate an IRQ to the network + * device. + * + * Input : a pointer to the network device structure + * + * Output : zero of success , nonzero if fails. + */ + +static int mv643xx_eth_open(struct net_device *dev) +{ + struct mv643xx_private *mp = netdev_priv(dev); + unsigned int port_num = mp->port_num; + int err; + + spin_lock_irq(&mp->lock); + + err = request_irq(dev->irq, mv643xx_eth_int_handler, + SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); + + if (err) { + printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n", + port_num); + err = -EAGAIN; + goto out; + } + + if (mv643xx_eth_real_open(dev)) { + printk("%s: Error opening interface\n", dev->name); + err = -EBUSY; + goto out_free; + } + + spin_unlock_irq(&mp->lock); + + return 0; + +out_free: + free_irq(dev->irq, dev); + +out: + spin_unlock_irq(&mp->lock); + + return err; +} + /* * ether_init_rx_desc_ring - Curve a Rx chain desc list and buffer in memory. * @@ -719,37 +777,28 @@ static void ether_init_tx_desc_ring(struct mv643xx_private *mp) mp->port_tx_queue_command |= 1; } -/* - * mv643xx_eth_open - * - * This function is called when openning the network device. The function - * should initialize all the hardware, initialize cyclic Rx/Tx - * descriptors chain and buffers and allocate an IRQ to the network - * device. - * - * Input : a pointer to the network device structure - * - * Output : zero of success , nonzero if fails. - */ - -static int mv643xx_eth_open(struct net_device *dev) +/* Helper function for mv643xx_eth_open */ +static int mv643xx_eth_real_open(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; unsigned int size; - int err; - - err = request_irq(dev->irq, mv643xx_eth_int_handler, - SA_SHIRQ | SA_SAMPLE_RANDOM, dev->name, dev); - if (err) { - printk(KERN_ERR "Can not assign IRQ number to MV643XX_eth%d\n", - port_num); - return -EAGAIN; - } /* Stop RX Queues */ mv_write(MV643XX_ETH_RECEIVE_QUEUE_COMMAND_REG(port_num), 0x0000ff00); + /* Clear the ethernet port interrupts */ + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); + + /* Unmask RX buffer and TX end interrupt */ + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), + INT_CAUSE_UNMASK_ALL); + + /* Unmask phy and link status changes interrupts */ + mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), + INT_CAUSE_UNMASK_ALL_EXT); + /* Set the MAC Address */ memcpy(mp->port_mac_addr, dev->dev_addr, 6); @@ -769,15 +818,14 @@ static int mv643xx_eth_open(struct net_device *dev) GFP_KERNEL); if (!mp->rx_skb) { printk(KERN_ERR "%s: Cannot allocate Rx skb ring\n", dev->name); - err = -ENOMEM; - goto out_free_irq; + return -ENOMEM; } mp->tx_skb = kmalloc(sizeof(*mp->tx_skb) * mp->tx_ring_size, GFP_KERNEL); if (!mp->tx_skb) { printk(KERN_ERR "%s: Cannot allocate Tx skb ring\n", dev->name); - err = -ENOMEM; - goto out_free_rx_skb; + kfree(mp->rx_skb); + return -ENOMEM; } /* Allocate TX ring */ @@ -797,8 +845,9 @@ static int mv643xx_eth_open(struct net_device *dev) if (!mp->p_tx_desc_area) { printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n", dev->name, size); - err = -ENOMEM; - goto out_free_tx_skb; + kfree(mp->rx_skb); + kfree(mp->tx_skb); + return -ENOMEM; } BUG_ON((u32) mp->p_tx_desc_area & 0xf); /* check 16-byte alignment */ memset((void *)mp->p_tx_desc_area, 0, mp->tx_desc_area_size); @@ -825,12 +874,13 @@ static int mv643xx_eth_open(struct net_device *dev) printk(KERN_ERR "%s: Freeing previously allocated TX queues...", dev->name); if (mp->rx_sram_size) - iounmap(mp->p_tx_desc_area); + iounmap(mp->p_rx_desc_area); else dma_free_coherent(NULL, mp->tx_desc_area_size, mp->p_tx_desc_area, mp->tx_desc_dma); - err = -ENOMEM; - goto out_free_tx_skb; + kfree(mp->rx_skb); + kfree(mp->tx_skb); + return -ENOMEM; } memset((void *)mp->p_rx_desc_area, 0, size); @@ -850,26 +900,9 @@ static int mv643xx_eth_open(struct net_device *dev) mp->tx_int_coal = eth_port_set_tx_coal(port_num, 133000000, MV643XX_TX_COAL); - /* Clear any pending ethernet port interrupts */ - mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); - mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); - - /* Unmask phy and link status changes interrupts */ - mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), - INT_UNMASK_ALL_EXT); + netif_start_queue(dev); - /* Unmask RX buffer and TX end interrupt */ - mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL); return 0; - -out_free_tx_skb: - kfree(mp->tx_skb); -out_free_rx_skb: - kfree(mp->rx_skb); -out_free_irq: - free_irq(dev->irq, dev); - - return err; } static void mv643xx_eth_free_tx_rings(struct net_device *dev) @@ -877,17 +910,14 @@ static void mv643xx_eth_free_tx_rings(struct net_device *dev) struct mv643xx_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; unsigned int curr; - struct sk_buff *skb; /* Stop Tx Queues */ mv_write(MV643XX_ETH_TRANSMIT_QUEUE_COMMAND_REG(port_num), 0x0000ff00); /* Free outstanding skb's on TX rings */ for (curr = 0; mp->tx_ring_skbs && curr < mp->tx_ring_size; curr++) { - skb = mp->tx_skb[curr]; - if (skb) { - mp->tx_ring_skbs -= skb_shinfo(skb)->nr_frags; - dev_kfree_skb(skb); + if (mp->tx_skb[curr]) { + dev_kfree_skb(mp->tx_skb[curr]); mp->tx_ring_skbs--; } } @@ -943,32 +973,44 @@ static void mv643xx_eth_free_rx_rings(struct net_device *dev) * Output : zero if success , nonzero if fails */ -static int mv643xx_eth_stop(struct net_device *dev) +/* Helper function for mv643xx_eth_stop */ + +static int mv643xx_eth_real_stop(struct net_device *dev) { struct mv643xx_private *mp = netdev_priv(dev); unsigned int port_num = mp->port_num; - /* Mask all interrupts on ethernet port */ - mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_MASK_ALL); - /* wait for previous write to complete */ - mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); - -#ifdef MV643XX_NAPI - netif_poll_disable(dev); -#endif netif_carrier_off(dev); netif_stop_queue(dev); - eth_port_reset(mp->port_num); - mv643xx_eth_free_tx_rings(dev); mv643xx_eth_free_rx_rings(dev); -#ifdef MV643XX_NAPI - netif_poll_enable(dev); -#endif + eth_port_reset(mp->port_num); + + /* Disable ethernet port interrupts */ + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); + mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); + + /* Mask RX buffer and TX end interrupt */ + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), 0); + + /* Mask phy and link status changes interrupts */ + mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), 0); + + return 0; +} + +static int mv643xx_eth_stop(struct net_device *dev) +{ + struct mv643xx_private *mp = netdev_priv(dev); + + spin_lock_irq(&mp->lock); + + mv643xx_eth_real_stop(dev); free_irq(dev->irq, dev); + spin_unlock_irq(&mp->lock); return 0; } @@ -980,17 +1022,20 @@ static void mv643xx_tx(struct net_device *dev) struct pkt_info pkt_info; while (eth_tx_return_desc(mp, &pkt_info) == ETH_OK) { - if (pkt_info.cmd_sts & ETH_TX_FIRST_DESC) - dma_unmap_single(NULL, pkt_info.buf_ptr, - pkt_info.byte_cnt, - DMA_TO_DEVICE); - else - dma_unmap_page(NULL, pkt_info.buf_ptr, - pkt_info.byte_cnt, - DMA_TO_DEVICE); + if (pkt_info.return_info) { + if (skb_shinfo(pkt_info.return_info)->nr_frags) + dma_unmap_page(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, + DMA_TO_DEVICE); + else + dma_unmap_single(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, + DMA_TO_DEVICE); - if (pkt_info.return_info) dev_kfree_skb_irq(pkt_info.return_info); + } else + dma_unmap_page(NULL, pkt_info.buf_ptr, + pkt_info.byte_cnt, DMA_TO_DEVICE); } if (netif_queue_stopped(dev) && @@ -1008,11 +1053,14 @@ static int mv643xx_poll(struct net_device *dev, int *budget) struct mv643xx_private *mp = netdev_priv(dev); int done = 1, orig_budget, work_done; unsigned int port_num = mp->port_num; + unsigned long flags; #ifdef MV643XX_TX_FAST_REFILL if (++mp->tx_clean_threshold > 5) { + spin_lock_irqsave(&mp->lock, flags); mv643xx_tx(dev); mp->tx_clean_threshold = 0; + spin_unlock_irqrestore(&mp->lock, flags); } #endif @@ -1030,36 +1078,21 @@ static int mv643xx_poll(struct net_device *dev, int *budget) } if (done) { - netif_rx_complete(dev); + spin_lock_irqsave(&mp->lock, flags); + __netif_rx_complete(dev); mv_write(MV643XX_ETH_INTERRUPT_CAUSE_REG(port_num), 0); mv_write(MV643XX_ETH_INTERRUPT_CAUSE_EXTEND_REG(port_num), 0); mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), - INT_UNMASK_ALL); + INT_CAUSE_UNMASK_ALL); + mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), + INT_CAUSE_UNMASK_ALL_EXT); + spin_unlock_irqrestore(&mp->lock, flags); } return done ? 0 : 1; } #endif -/* Hardware can't handle unaligned fragments smaller than 9 bytes. - * This helper function detects that case. - */ - -static inline unsigned int has_tiny_unaligned_frags(struct sk_buff *skb) -{ - unsigned int frag; - skb_frag_t *fragp; - - for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { - fragp = &skb_shinfo(skb)->frags[frag]; - if (fragp->size <= 8 && fragp->page_offset & 0x7) - return 1; - - } - return 0; -} - - /* * mv643xx_eth_start_xmit * @@ -1103,19 +1136,12 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) return 1; } -#ifdef MV643XX_CHECKSUM_OFFLOAD_TX - if (has_tiny_unaligned_frags(skb)) { - if ((skb_linearize(skb, GFP_ATOMIC) != 0)) { - stats->tx_dropped++; - printk(KERN_DEBUG "%s: failed to linearize tiny " - "unaligned fragment\n", dev->name); - return 1; - } - } - spin_lock_irqsave(&mp->lock, flags); + /* Update packet info data structure -- DMA owned, first last */ +#ifdef MV643XX_CHECKSUM_OFFLOAD_TX if (!skb_shinfo(skb)->nr_frags) { +linear: if (skb->ip_summed != CHECKSUM_HW) { /* Errata BTS #50, IHL must be 5 if no HW checksum */ pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | @@ -1124,6 +1150,7 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) 5 << ETH_TX_IHL_SHIFT; pkt_info.l4i_chk = 0; } else { + pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC | @@ -1131,16 +1158,14 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) ETH_GEN_IP_V_4_CHECKSUM | skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; /* CPU already calculated pseudo header checksum. */ - if ((skb->protocol == ETH_P_IP) && - (skb->nh.iph->protocol == IPPROTO_UDP) ) { + if (skb->nh.iph->protocol == IPPROTO_UDP) { pkt_info.cmd_sts |= ETH_UDP_FRAME; pkt_info.l4i_chk = skb->h.uh->check; - } else if ((skb->protocol == ETH_P_IP) && - (skb->nh.iph->protocol == IPPROTO_TCP)) + } else if (skb->nh.iph->protocol == IPPROTO_TCP) pkt_info.l4i_chk = skb->h.th->check; else { printk(KERN_ERR - "%s: chksum proto != IPv4 TCP or UDP\n", + "%s: chksum proto != TCP or UDP\n", dev->name); spin_unlock_irqrestore(&mp->lock, flags); return 1; @@ -1158,6 +1183,26 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) } else { unsigned int frag; + /* Since hardware can't handle unaligned fragments smaller + * than 9 bytes, if we find any, we linearize the skb + * and start again. When I've seen it, it's always been + * the first frag (probably near the end of the page), + * but we check all frags to be safe. + */ + for (frag = 0; frag < skb_shinfo(skb)->nr_frags; frag++) { + skb_frag_t *fragp; + + fragp = &skb_shinfo(skb)->frags[frag]; + if (fragp->size <= 8 && fragp->page_offset & 0x7) { + skb_linearize(skb, GFP_ATOMIC); + printk(KERN_DEBUG "%s: unaligned tiny fragment" + "%d of %d, fixed\n", + dev->name, frag, + skb_shinfo(skb)->nr_frags); + goto linear; + } + } + /* first frag which is skb header */ pkt_info.byte_cnt = skb_headlen(skb); pkt_info.buf_ptr = dma_map_single(NULL, skb->data, @@ -1176,16 +1221,14 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) ETH_GEN_IP_V_4_CHECKSUM | skb->nh.iph->ihl << ETH_TX_IHL_SHIFT; /* CPU already calculated pseudo header checksum. */ - if ((skb->protocol == ETH_P_IP) && - (skb->nh.iph->protocol == IPPROTO_UDP)) { + if (skb->nh.iph->protocol == IPPROTO_UDP) { pkt_info.cmd_sts |= ETH_UDP_FRAME; pkt_info.l4i_chk = skb->h.uh->check; - } else if ((skb->protocol == ETH_P_IP) && - (skb->nh.iph->protocol == IPPROTO_TCP)) + } else if (skb->nh.iph->protocol == IPPROTO_TCP) pkt_info.l4i_chk = skb->h.th->check; else { printk(KERN_ERR - "%s: chksum proto != IPv4 TCP or UDP\n", + "%s: chksum proto != TCP or UDP\n", dev->name); spin_unlock_irqrestore(&mp->lock, flags); return 1; @@ -1245,8 +1288,6 @@ static int mv643xx_eth_start_xmit(struct sk_buff *skb, struct net_device *dev) } } #else - spin_lock_irqsave(&mp->lock, flags); - pkt_info.cmd_sts = ETH_TX_ENABLE_INTERRUPT | ETH_TX_FIRST_DESC | ETH_TX_LAST_DESC; pkt_info.l4i_chk = 0; @@ -1299,18 +1340,39 @@ static struct net_device_stats *mv643xx_eth_get_stats(struct net_device *dev) } #ifdef CONFIG_NET_POLL_CONTROLLER -static void mv643xx_netpoll(struct net_device *netdev) +static inline void mv643xx_enable_irq(struct mv643xx_private *mp) +{ + int port_num = mp->port_num; + unsigned long flags; + + spin_lock_irqsave(&mp->lock, flags); + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), + INT_CAUSE_UNMASK_ALL); + mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), + INT_CAUSE_UNMASK_ALL_EXT); + spin_unlock_irqrestore(&mp->lock, flags); +} + +static inline void mv643xx_disable_irq(struct mv643xx_private *mp) { - struct mv643xx_private *mp = netdev_priv(netdev); int port_num = mp->port_num; + unsigned long flags; - mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_MASK_ALL); - /* wait for previous write to complete */ - mv_read(MV643XX_ETH_INTERRUPT_MASK_REG(port_num)); + spin_lock_irqsave(&mp->lock, flags); + mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), + INT_CAUSE_MASK_ALL); + mv_write(MV643XX_ETH_INTERRUPT_EXTEND_MASK_REG(port_num), + INT_CAUSE_MASK_ALL_EXT); + spin_unlock_irqrestore(&mp->lock, flags); +} - mv643xx_eth_int_handler(netdev->irq, netdev, NULL); +static void mv643xx_netpoll(struct net_device *netdev) +{ + struct mv643xx_private *mp = netdev_priv(netdev); - mv_write(MV643XX_ETH_INTERRUPT_MASK_REG(port_num), INT_UNMASK_ALL); + mv643xx_disable_irq(mp); + mv643xx_eth_int_handler(netdev->irq, netdev, NULL); + mv643xx_enable_irq(mp); } #endif @@ -1379,7 +1441,7 @@ static int mv643xx_eth_probe(struct platform_device *pdev) * Zero copy can only work if we use Discovery II memory. Else, we will * have to map the buffers to ISA memory which is only 16 MB */ - dev->features = NETIF_F_SG | NETIF_F_IP_CSUM; + dev->features = NETIF_F_SG | NETIF_F_IP_CSUM | NETIF_F_HW_CSUM; #endif #endif @@ -1991,196 +2053,6 @@ static int eth_port_uc_addr(unsigned int eth_port_num, unsigned char uc_nibble, return 1; } -/* - * The entries in each table are indexed by a hash of a packet's MAC - * address. One bit in each entry determines whether the packet is - * accepted. There are 4 entries (each 8 bits wide) in each register - * of the table. The bits in each entry are defined as follows: - * 0 Accept=1, Drop=0 - * 3-1 Queue (ETH_Q0=0) - * 7-4 Reserved = 0; - */ -static void eth_port_set_filter_table_entry(int table, unsigned char entry) -{ - unsigned int table_reg; - unsigned int tbl_offset; - unsigned int reg_offset; - - tbl_offset = (entry / 4) * 4; /* Register offset of DA table entry */ - reg_offset = entry % 4; /* Entry offset within the register */ - - /* Set "accepts frame bit" at specified table entry */ - table_reg = mv_read(table + tbl_offset); - table_reg |= 0x01 << (8 * reg_offset); - mv_write(table + tbl_offset, table_reg); -} - -/* - * eth_port_mc_addr - Multicast address settings. - * - * The MV device supports multicast using two tables: - * 1) Special Multicast Table for MAC addresses of the form - * 0x01-00-5E-00-00-XX (where XX is between 0x00 and 0x_FF). - * The MAC DA[7:0] bits are used as a pointer to the Special Multicast - * Table entries in the DA-Filter table. - * 2) Other Multicast Table for multicast of another type. A CRC-8bit - * is used as an index to the Other Multicast Table entries in the - * DA-Filter table. This function calculates the CRC-8bit value. - * In either case, eth_port_set_filter_table_entry() is then called - * to set to set the actual table entry. - */ -static void eth_port_mc_addr(unsigned int eth_port_num, unsigned char *p_addr) -{ - unsigned int mac_h; - unsigned int mac_l; - unsigned char crc_result = 0; - int table; - int mac_array[48]; - int crc[8]; - int i; - - if ((p_addr[0] == 0x01) && (p_addr[1] == 0x00) && - (p_addr[2] == 0x5E) && (p_addr[3] == 0x00) && (p_addr[4] == 0x00)) { - table = MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE - (eth_port_num); - eth_port_set_filter_table_entry(table, p_addr[5]); - return; - } - - /* Calculate CRC-8 out of the given address */ - mac_h = (p_addr[0] << 8) | (p_addr[1]); - mac_l = (p_addr[2] << 24) | (p_addr[3] << 16) | - (p_addr[4] << 8) | (p_addr[5] << 0); - - for (i = 0; i < 32; i++) - mac_array[i] = (mac_l >> i) & 0x1; - for (i = 32; i < 48; i++) - mac_array[i] = (mac_h >> (i - 32)) & 0x1; - - crc[0] = mac_array[45] ^ mac_array[43] ^ mac_array[40] ^ mac_array[39] ^ - mac_array[35] ^ mac_array[34] ^ mac_array[31] ^ mac_array[30] ^ - mac_array[28] ^ mac_array[23] ^ mac_array[21] ^ mac_array[19] ^ - mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ mac_array[12] ^ - mac_array[8] ^ mac_array[7] ^ mac_array[6] ^ mac_array[0]; - - crc[1] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^ - mac_array[41] ^ mac_array[39] ^ mac_array[36] ^ mac_array[34] ^ - mac_array[32] ^ mac_array[30] ^ mac_array[29] ^ mac_array[28] ^ - mac_array[24] ^ mac_array[23] ^ mac_array[22] ^ mac_array[21] ^ - mac_array[20] ^ mac_array[18] ^ mac_array[17] ^ mac_array[16] ^ - mac_array[15] ^ mac_array[14] ^ mac_array[13] ^ mac_array[12] ^ - mac_array[9] ^ mac_array[6] ^ mac_array[1] ^ mac_array[0]; - - crc[2] = mac_array[47] ^ mac_array[46] ^ mac_array[44] ^ mac_array[43] ^ - mac_array[42] ^ mac_array[39] ^ mac_array[37] ^ mac_array[34] ^ - mac_array[33] ^ mac_array[29] ^ mac_array[28] ^ mac_array[25] ^ - mac_array[24] ^ mac_array[22] ^ mac_array[17] ^ mac_array[15] ^ - mac_array[13] ^ mac_array[12] ^ mac_array[10] ^ mac_array[8] ^ - mac_array[6] ^ mac_array[2] ^ mac_array[1] ^ mac_array[0]; - - crc[3] = mac_array[47] ^ mac_array[45] ^ mac_array[44] ^ mac_array[43] ^ - mac_array[40] ^ mac_array[38] ^ mac_array[35] ^ mac_array[34] ^ - mac_array[30] ^ mac_array[29] ^ mac_array[26] ^ mac_array[25] ^ - mac_array[23] ^ mac_array[18] ^ mac_array[16] ^ mac_array[14] ^ - mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[7] ^ - mac_array[3] ^ mac_array[2] ^ mac_array[1]; - - crc[4] = mac_array[46] ^ mac_array[45] ^ mac_array[44] ^ mac_array[41] ^ - mac_array[39] ^ mac_array[36] ^ mac_array[35] ^ mac_array[31] ^ - mac_array[30] ^ mac_array[27] ^ mac_array[26] ^ mac_array[24] ^ - mac_array[19] ^ mac_array[17] ^ mac_array[15] ^ mac_array[14] ^ - mac_array[12] ^ mac_array[10] ^ mac_array[8] ^ mac_array[4] ^ - mac_array[3] ^ mac_array[2]; - - crc[5] = mac_array[47] ^ mac_array[46] ^ mac_array[45] ^ mac_array[42] ^ - mac_array[40] ^ mac_array[37] ^ mac_array[36] ^ mac_array[32] ^ - mac_array[31] ^ mac_array[28] ^ mac_array[27] ^ mac_array[25] ^ - mac_array[20] ^ mac_array[18] ^ mac_array[16] ^ mac_array[15] ^ - mac_array[13] ^ mac_array[11] ^ mac_array[9] ^ mac_array[5] ^ - mac_array[4] ^ mac_array[3]; - - crc[6] = mac_array[47] ^ mac_array[46] ^ mac_array[43] ^ mac_array[41] ^ - mac_array[38] ^ mac_array[37] ^ mac_array[33] ^ mac_array[32] ^ - mac_array[29] ^ mac_array[28] ^ mac_array[26] ^ mac_array[21] ^ - mac_array[19] ^ mac_array[17] ^ mac_array[16] ^ mac_array[14] ^ - mac_array[12] ^ mac_array[10] ^ mac_array[6] ^ mac_array[5] ^ - mac_array[4]; - - crc[7] = mac_array[47] ^ mac_array[44] ^ mac_array[42] ^ mac_array[39] ^ - mac_array[38] ^ mac_array[34] ^ mac_array[33] ^ mac_array[30] ^ - mac_array[29] ^ mac_array[27] ^ mac_array[22] ^ mac_array[20] ^ - mac_array[18] ^ mac_array[17] ^ mac_array[15] ^ mac_array[13] ^ - mac_array[11] ^ mac_array[7] ^ mac_array[6] ^ mac_array[5]; - - for (i = 0; i < 8; i++) - crc_result = crc_result | (crc[i] << i); - - table = MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num); - eth_port_set_filter_table_entry(table, crc_result); -} - -/* - * Set the entire multicast list based on dev->mc_list. - */ -static void eth_port_set_multicast_list(struct net_device *dev) -{ - - struct dev_mc_list *mc_list; - int i; - int table_index; - struct mv643xx_private *mp = netdev_priv(dev); - unsigned int eth_port_num = mp->port_num; - - /* If the device is in promiscuous mode or in all multicast mode, - * we will fully populate both multicast tables with accept. - * This is guaranteed to yield a match on all multicast addresses... - */ - if ((dev->flags & IFF_PROMISC) || (dev->flags & IFF_ALLMULTI)) { - for (table_index = 0; table_index <= 0xFC; table_index += 4) { - /* Set all entries in DA filter special multicast - * table (Ex_dFSMT) - * Set for ETH_Q0 for now - * Bits - * 0 Accept=1, Drop=0 - * 3-1 Queue ETH_Q0=0 - * 7-4 Reserved = 0; - */ - mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); - - /* Set all entries in DA filter other multicast - * table (Ex_dFOMT) - * Set for ETH_Q0 for now - * Bits - * 0 Accept=1, Drop=0 - * 3-1 Queue ETH_Q0=0 - * 7-4 Reserved = 0; - */ - mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE(eth_port_num) + table_index, 0x01010101); - } - return; - } - - /* We will clear out multicast tables every time we get the list. - * Then add the entire new list... - */ - for (table_index = 0; table_index <= 0xFC; table_index += 4) { - /* Clear DA filter special multicast table (Ex_dFSMT) */ - mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE - (eth_port_num) + table_index, 0); - - /* Clear DA filter other multicast table (Ex_dFOMT) */ - mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE - (eth_port_num) + table_index, 0); - } - - /* Get pointer to net_device multicast list and add each one... */ - for (i = 0, mc_list = dev->mc_list; - (i < 256) && (mc_list != NULL) && (i < dev->mc_count); - i++, mc_list = mc_list->next) - if (mc_list->dmi_addrlen == 6) - eth_port_mc_addr(eth_port_num, mc_list->dmi_addr); -} - /* * eth_port_init_mac_tables - Clear all entrance in the UC, SMC and OMC tables * @@ -2208,11 +2080,11 @@ static void eth_port_init_mac_tables(unsigned int eth_port_num) for (table_index = 0; table_index <= 0xFC; table_index += 4) { /* Clear DA filter special multicast table (Ex_dFSMT) */ - mv_write(MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE - (eth_port_num) + table_index, 0); + mv_write((MV643XX_ETH_DA_FILTER_SPECIAL_MULTICAST_TABLE_BASE + (eth_port_num) + table_index), 0); /* Clear DA filter other multicast table (Ex_dFOMT) */ - mv_write(MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE - (eth_port_num) + table_index, 0); + mv_write((MV643XX_ETH_DA_FILTER_OTHER_MULTICAST_TABLE_BASE + (eth_port_num) + table_index), 0); } } @@ -2617,7 +2489,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, struct eth_tx_desc *current_descriptor; struct eth_tx_desc *first_descriptor; u32 command; - unsigned long flags; /* Do not process Tx ring in case of Tx ring resource error */ if (mp->tx_resource_err) @@ -2634,8 +2505,6 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, return ETH_ERROR; } - spin_lock_irqsave(&mp->lock, flags); - mp->tx_ring_skbs++; BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); @@ -2685,15 +2554,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, mp->tx_resource_err = 1; mp->tx_curr_desc_q = tx_first_desc; - spin_unlock_irqrestore(&mp->lock, flags); - return ETH_QUEUE_LAST_RESOURCE; } mp->tx_curr_desc_q = tx_next_desc; - spin_unlock_irqrestore(&mp->lock, flags); - return ETH_OK; } #else @@ -2704,14 +2569,11 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, int tx_desc_used; struct eth_tx_desc *current_descriptor; unsigned int command_status; - unsigned long flags; /* Do not process Tx ring in case of Tx ring resource error */ if (mp->tx_resource_err) return ETH_QUEUE_FULL; - spin_lock_irqsave(&mp->lock, flags); - mp->tx_ring_skbs++; BUG_ON(mp->tx_ring_skbs > mp->tx_ring_size); @@ -2742,12 +2604,9 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, /* Check for ring index overlap in the Tx desc ring */ if (tx_desc_curr == tx_desc_used) { mp->tx_resource_err = 1; - - spin_unlock_irqrestore(&mp->lock, flags); return ETH_QUEUE_LAST_RESOURCE; } - spin_unlock_irqrestore(&mp->lock, flags); return ETH_OK; } #endif @@ -2770,27 +2629,23 @@ static ETH_FUNC_RET_STATUS eth_port_send(struct mv643xx_private *mp, * Tx ring 'first' and 'used' indexes are updated. * * RETURN: - * ETH_OK on success - * ETH_ERROR otherwise. + * ETH_ERROR in case the routine can not access Tx desc ring. + * ETH_RETRY in case there is transmission in process. + * ETH_END_OF_JOB if the routine has nothing to release. + * ETH_OK otherwise. * */ static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp, struct pkt_info *p_pkt_info) { int tx_desc_used; - int tx_busy_desc; - struct eth_tx_desc *p_tx_desc_used; - unsigned int command_status; - unsigned long flags; - int err = ETH_OK; - - spin_lock_irqsave(&mp->lock, flags); - #ifdef MV643XX_CHECKSUM_OFFLOAD_TX - tx_busy_desc = mp->tx_first_desc_q; + int tx_busy_desc = mp->tx_first_desc_q; #else - tx_busy_desc = mp->tx_curr_desc_q; + int tx_busy_desc = mp->tx_curr_desc_q; #endif + struct eth_tx_desc *p_tx_desc_used; + unsigned int command_status; /* Get the Tx Desc ring indexes */ tx_desc_used = mp->tx_used_desc_q; @@ -2798,30 +2653,22 @@ static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp, p_tx_desc_used = &mp->p_tx_desc_area[tx_desc_used]; /* Sanity check */ - if (p_tx_desc_used == NULL) { - err = ETH_ERROR; - goto out; - } + if (p_tx_desc_used == NULL) + return ETH_ERROR; /* Stop release. About to overlap the current available Tx descriptor */ - if (tx_desc_used == tx_busy_desc && !mp->tx_resource_err) { - err = ETH_ERROR; - goto out; - } + if (tx_desc_used == tx_busy_desc && !mp->tx_resource_err) + return ETH_END_OF_JOB; command_status = p_tx_desc_used->cmd_sts; /* Still transmitting... */ - if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) { - err = ETH_ERROR; - goto out; - } + if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) + return ETH_RETRY; /* Pass the packet information to the caller */ p_pkt_info->cmd_sts = command_status; p_pkt_info->return_info = mp->tx_skb[tx_desc_used]; - p_pkt_info->buf_ptr = p_tx_desc_used->buf_ptr; - p_pkt_info->byte_cnt = p_tx_desc_used->byte_cnt; mp->tx_skb[tx_desc_used] = NULL; /* Update the next descriptor to release. */ @@ -2833,10 +2680,7 @@ static ETH_FUNC_RET_STATUS eth_tx_return_desc(struct mv643xx_private *mp, BUG_ON(mp->tx_ring_skbs == 0); mp->tx_ring_skbs--; -out: - spin_unlock_irqrestore(&mp->lock, flags); - - return err; + return ETH_OK; } /* @@ -2868,14 +2712,11 @@ static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp, int rx_next_curr_desc, rx_curr_desc, rx_used_desc; volatile struct eth_rx_desc *p_rx_desc; unsigned int command_status; - unsigned long flags; /* Do not process Rx ring in case of Rx ring resource error */ if (mp->rx_resource_err) return ETH_QUEUE_FULL; - spin_lock_irqsave(&mp->lock, flags); - /* Get the Rx Desc ring 'curr and 'used' indexes */ rx_curr_desc = mp->rx_curr_desc_q; rx_used_desc = mp->rx_used_desc_q; @@ -2887,10 +2728,8 @@ static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp, rmb(); /* Nothing to receive... */ - if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) { - spin_unlock_irqrestore(&mp->lock, flags); + if (command_status & (ETH_BUFFER_OWNED_BY_DMA)) return ETH_END_OF_JOB; - } p_pkt_info->byte_cnt = (p_rx_desc->byte_cnt) - RX_BUF_OFFSET; p_pkt_info->cmd_sts = command_status; @@ -2910,8 +2749,6 @@ static ETH_FUNC_RET_STATUS eth_port_receive(struct mv643xx_private *mp, if (rx_next_curr_desc == rx_used_desc) mp->rx_resource_err = 1; - spin_unlock_irqrestore(&mp->lock, flags); - return ETH_OK; } @@ -2940,9 +2777,6 @@ static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp, { int used_rx_desc; /* Where to return Rx resource */ volatile struct eth_rx_desc *p_used_rx_desc; - unsigned long flags; - - spin_lock_irqsave(&mp->lock, flags); /* Get 'used' Rx descriptor */ used_rx_desc = mp->rx_used_desc_q; @@ -2966,8 +2800,6 @@ static ETH_FUNC_RET_STATUS eth_rx_return_buff(struct mv643xx_private *mp, /* Any Rx return cancels the Rx resource error status */ mp->rx_resource_err = 0; - spin_unlock_irqrestore(&mp->lock, flags); - return ETH_OK; } diff --git a/trunk/drivers/net/sk98lin/h/skaddr.h b/trunk/drivers/net/sk98lin/h/skaddr.h index 3a2ea4a4b539..423ad063d09b 100644 --- a/trunk/drivers/net/sk98lin/h/skaddr.h +++ b/trunk/drivers/net/sk98lin/h/skaddr.h @@ -236,18 +236,6 @@ extern int SkAddrMcClear( SK_U32 PortNumber, int Flags); -extern int SkAddrXmacMcClear( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - int Flags); - -extern int SkAddrGmacMcClear( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - int Flags); - extern int SkAddrMcAdd( SK_AC *pAC, SK_IOC IoC, @@ -255,35 +243,11 @@ extern int SkAddrMcAdd( SK_MAC_ADDR *pMc, int Flags); -extern int SkAddrXmacMcAdd( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - SK_MAC_ADDR *pMc, - int Flags); - -extern int SkAddrGmacMcAdd( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - SK_MAC_ADDR *pMc, - int Flags); - extern int SkAddrMcUpdate( SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); -extern int SkAddrXmacMcUpdate( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber); - -extern int SkAddrGmacMcUpdate( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber); - extern int SkAddrOverride( SK_AC *pAC, SK_IOC IoC, @@ -297,18 +261,6 @@ extern int SkAddrPromiscuousChange( SK_U32 PortNumber, int NewPromMode); -extern int SkAddrXmacPromiscuousChange( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - int NewPromMode); - -extern int SkAddrGmacPromiscuousChange( - SK_AC *pAC, - SK_IOC IoC, - SK_U32 PortNumber, - int NewPromMode); - #ifndef SK_SLIM extern int SkAddrSwap( SK_AC *pAC, diff --git a/trunk/drivers/net/sk98lin/h/skcsum.h b/trunk/drivers/net/sk98lin/h/skcsum.h index 2b94adb93331..6e256bd9a28c 100644 --- a/trunk/drivers/net/sk98lin/h/skcsum.h +++ b/trunk/drivers/net/sk98lin/h/skcsum.h @@ -203,12 +203,6 @@ extern SKCS_STATUS SkCsGetReceiveInfo( unsigned Checksum2, int NetNumber); -extern void SkCsGetSendInfo( - SK_AC *pAc, - void *pIpHeader, - SKCS_PACKET_INFO *pPacketInfo, - int NetNumber); - extern void SkCsSetReceiveFlags( SK_AC *pAc, unsigned ReceiveFlags, diff --git a/trunk/drivers/net/sk98lin/h/skgeinit.h b/trunk/drivers/net/sk98lin/h/skgeinit.h index 184f47c5a60f..143e635ec24d 100644 --- a/trunk/drivers/net/sk98lin/h/skgeinit.h +++ b/trunk/drivers/net/sk98lin/h/skgeinit.h @@ -464,12 +464,6 @@ typedef struct s_GeInit { /* * public functions in skgeinit.c */ -extern void SkGePollRxD( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_BOOL PollRxD); - extern void SkGePollTxD( SK_AC *pAC, SK_IOC IoC, @@ -522,10 +516,6 @@ extern void SkGeXmitLED( int Led, int Mode); -extern void SkGeInitRamIface( - SK_AC *pAC, - SK_IOC IoC); - extern int SkGeInitAssignRamToQueues( SK_AC *pAC, int ActivePort, @@ -549,11 +539,6 @@ extern void SkMacHardRst( SK_IOC IoC, int Port); -extern void SkMacClearRst( - SK_AC *pAC, - SK_IOC IoC, - int Port); - extern void SkXmInitMac( SK_AC *pAC, SK_IOC IoC, @@ -580,11 +565,6 @@ extern void SkMacFlushTxFifo( SK_IOC IoC, int Port); -extern void SkMacFlushRxFifo( - SK_AC *pAC, - SK_IOC IoC, - int Port); - extern void SkMacIrq( SK_AC *pAC, SK_IOC IoC, @@ -601,12 +581,6 @@ extern void SkMacAutoNegLipaPhy( int Port, SK_U16 IStatus); -extern void SkMacSetRxTxEn( - SK_AC *pAC, - SK_IOC IoC, - int Port, - int Para); - extern int SkMacRxTxEnable( SK_AC *pAC, SK_IOC IoC, @@ -659,16 +633,6 @@ extern void SkXmClrExactAddr( int StartNum, int StopNum); -extern void SkXmInitDupMd( - SK_AC *pAC, - SK_IOC IoC, - int Port); - -extern void SkXmInitPauseMd( - SK_AC *pAC, - SK_IOC IoC, - int Port); - extern void SkXmAutoNegLipaXmac( SK_AC *pAC, SK_IOC IoC, @@ -729,17 +693,6 @@ extern int SkGmCableDiagStatus( int Port, SK_BOOL StartTest); -extern int SkGmEnterLowPowerMode( - SK_AC *pAC, - SK_IOC IoC, - int Port, - SK_U8 Mode); - -extern int SkGmLeaveLowPowerMode( - SK_AC *pAC, - SK_IOC IoC, - int Port); - #ifdef SK_DIAG extern void SkGePhyRead( SK_AC *pAC, @@ -782,7 +735,6 @@ extern void SkXmSendCont( /* * public functions in skgeinit.c */ -extern void SkGePollRxD(); extern void SkGePollTxD(); extern void SkGeYellowLED(); extern int SkGeCfgSync(); @@ -792,7 +744,6 @@ extern int SkGeInit(); extern void SkGeDeInit(); extern int SkGeInitPort(); extern void SkGeXmitLED(); -extern void SkGeInitRamIface(); extern int SkGeInitAssignRamToQueues(); /* @@ -801,18 +752,15 @@ extern int SkGeInitAssignRamToQueues(); extern void SkMacRxTxDisable(); extern void SkMacSoftRst(); extern void SkMacHardRst(); -extern void SkMacClearRst(); extern void SkMacInitPhy(); extern int SkMacRxTxEnable(); extern void SkMacPromiscMode(); extern void SkMacHashing(); extern void SkMacIrqDisable(); extern void SkMacFlushTxFifo(); -extern void SkMacFlushRxFifo(); extern void SkMacIrq(); extern int SkMacAutoNegDone(); extern void SkMacAutoNegLipaPhy(); -extern void SkMacSetRxTxEn(); extern void SkXmInitMac(); extern void SkXmPhyRead(); extern void SkXmPhyWrite(); @@ -820,8 +768,6 @@ extern void SkGmInitMac(); extern void SkGmPhyRead(); extern void SkGmPhyWrite(); extern void SkXmClrExactAddr(); -extern void SkXmInitDupMd(); -extern void SkXmInitPauseMd(); extern void SkXmAutoNegLipaXmac(); extern int SkXmUpdateStats(); extern int SkGmUpdateStats(); @@ -832,8 +778,6 @@ extern int SkGmResetCounter(); extern int SkXmOverflowStatus(); extern int SkGmOverflowStatus(); extern int SkGmCableDiagStatus(); -extern int SkGmEnterLowPowerMode(); -extern int SkGmLeaveLowPowerMode(); #ifdef SK_DIAG extern void SkGePhyRead(); diff --git a/trunk/drivers/net/sk98lin/h/skgepnmi.h b/trunk/drivers/net/sk98lin/h/skgepnmi.h index 3b2773e6f822..1ed214ccb253 100644 --- a/trunk/drivers/net/sk98lin/h/skgepnmi.h +++ b/trunk/drivers/net/sk98lin/h/skgepnmi.h @@ -946,10 +946,6 @@ typedef struct s_PnmiData { * Function prototypes */ extern int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int Level); -extern int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, - unsigned int* pLen, SK_U32 Instance, SK_U32 NetIndex); -extern int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, - void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); extern int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void* pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); extern int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void* pBuf, diff --git a/trunk/drivers/net/sk98lin/h/skgesirq.h b/trunk/drivers/net/sk98lin/h/skgesirq.h index b486bd9b6628..3eec6274e413 100644 --- a/trunk/drivers/net/sk98lin/h/skgesirq.h +++ b/trunk/drivers/net/sk98lin/h/skgesirq.h @@ -105,7 +105,6 @@ extern void SkGeSirqIsr(SK_AC *pAC, SK_IOC IoC, SK_U32 Istatus); extern int SkGeSirqEvent(SK_AC *pAC, SK_IOC IoC, SK_U32 Event, SK_EVPARA Para); -extern void SkHWLinkUp(SK_AC *pAC, SK_IOC IoC, int Port); extern void SkHWLinkDown(SK_AC *pAC, SK_IOC IoC, int Port); #endif /* _INC_SKGESIRQ_H_ */ diff --git a/trunk/drivers/net/sk98lin/h/ski2c.h b/trunk/drivers/net/sk98lin/h/ski2c.h index 598bb42ccc3d..6a63f4a15de6 100644 --- a/trunk/drivers/net/sk98lin/h/ski2c.h +++ b/trunk/drivers/net/sk98lin/h/ski2c.h @@ -162,9 +162,6 @@ typedef struct s_I2c { } SK_I2C; extern int SkI2cInit(SK_AC *pAC, SK_IOC IoC, int Level); -extern int SkI2cWrite(SK_AC *pAC, SK_IOC IoC, SK_U32 Data, int Dev, int Size, - int Reg, int Burst); -extern int SkI2cReadSensor(SK_AC *pAC, SK_IOC IoC, SK_SENSOR *pSen); #ifdef SK_DIAG extern SK_U32 SkI2cRead(SK_AC *pAC, SK_IOC IoC, int Dev, int Size, int Reg, int Burst); diff --git a/trunk/drivers/net/sk98lin/h/skvpd.h b/trunk/drivers/net/sk98lin/h/skvpd.h index daa9a8d154fc..fdd9e48e8040 100644 --- a/trunk/drivers/net/sk98lin/h/skvpd.h +++ b/trunk/drivers/net/sk98lin/h/skvpd.h @@ -183,14 +183,6 @@ extern SK_U32 VpdReadDWord( int addr); #endif /* SKDIAG */ -extern int VpdSetupPara( - SK_AC *pAC, - const char *key, - const char *buf, - int len, - int type, - int op); - extern SK_VPD_STATUS *VpdStat( SK_AC *pAC, SK_IOC IoC); @@ -227,11 +219,6 @@ extern int VpdUpdate( SK_AC *pAC, SK_IOC IoC); -extern void VpdErrLog( - SK_AC *pAC, - SK_IOC IoC, - char *msg); - #ifdef SKDIAG extern int VpdReadBlock( SK_AC *pAC, @@ -249,7 +236,6 @@ extern int VpdWriteBlock( #endif /* SKDIAG */ #else /* SK_KR_PROTO */ extern SK_U32 VpdReadDWord(); -extern int VpdSetupPara(); extern SK_VPD_STATUS *VpdStat(); extern int VpdKeys(); extern int VpdRead(); @@ -257,7 +243,6 @@ extern SK_BOOL VpdMayWrite(); extern int VpdWrite(); extern int VpdDelete(); extern int VpdUpdate(); -extern void VpdErrLog(); #endif /* SK_KR_PROTO */ #endif /* __INC_SKVPD_H_ */ diff --git a/trunk/drivers/net/sk98lin/skaddr.c b/trunk/drivers/net/sk98lin/skaddr.c index a7e25edc7fc4..6e6c56aa6d6f 100644 --- a/trunk/drivers/net/sk98lin/skaddr.c +++ b/trunk/drivers/net/sk98lin/skaddr.c @@ -87,6 +87,21 @@ static const SK_U16 OnesHash[4] = {0xFFFF, 0xFFFF, 0xFFFF, 0xFFFF}; static int Next0[SK_MAX_MACS] = {0}; #endif /* DEBUG */ +static int SkAddrGmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, + SK_MAC_ADDR *pMc, int Flags); +static int SkAddrGmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, + int Flags); +static int SkAddrGmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); +static int SkAddrGmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, + SK_U32 PortNumber, int NewPromMode); +static int SkAddrXmacMcAdd(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, + SK_MAC_ADDR *pMc, int Flags); +static int SkAddrXmacMcClear(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber, + int Flags); +static int SkAddrXmacMcUpdate(SK_AC *pAC, SK_IOC IoC, SK_U32 PortNumber); +static int SkAddrXmacPromiscuousChange(SK_AC *pAC, SK_IOC IoC, + SK_U32 PortNumber, int NewPromMode); + /* functions ******************************************************************/ /****************************************************************************** @@ -372,7 +387,7 @@ int Flags) /* permanent/non-perm, sw-only */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -int SkAddrXmacMcClear( +static int SkAddrXmacMcClear( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Index of affected port */ @@ -429,7 +444,7 @@ int Flags) /* permanent/non-perm, sw-only */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -int SkAddrGmacMcClear( +static int SkAddrGmacMcClear( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Index of affected port */ @@ -519,7 +534,7 @@ int Flags) /* permanent/non-perm, sw-only */ * Returns: * Hash value of multicast address. */ -SK_U32 SkXmacMcHash( +static SK_U32 SkXmacMcHash( unsigned char *pMc) /* Multicast address */ { SK_U32 Idx; @@ -557,7 +572,7 @@ unsigned char *pMc) /* Multicast address */ * Returns: * Hash value of multicast address. */ -SK_U32 SkGmacMcHash( +static SK_U32 SkGmacMcHash( unsigned char *pMc) /* Multicast address */ { SK_U32 Data; @@ -672,7 +687,7 @@ int Flags) /* permanent/non-permanent */ * SK_MC_ILLEGAL_ADDRESS * SK_MC_RLMT_OVERFLOW */ -int SkAddrXmacMcAdd( +static int SkAddrXmacMcAdd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Port Number */ @@ -778,7 +793,7 @@ int Flags) /* permanent/non-permanent */ * SK_MC_FILTERING_INEXACT * SK_MC_ILLEGAL_ADDRESS */ -int SkAddrGmacMcAdd( +static int SkAddrGmacMcAdd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* Port Number */ @@ -937,7 +952,7 @@ SK_U32 PortNumber) /* Port Number */ * SK_MC_FILTERING_INEXACT * SK_ADDR_ILLEGAL_PORT */ -int SkAddrXmacMcUpdate( +static int SkAddrXmacMcUpdate( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber) /* Port Number */ @@ -1082,7 +1097,7 @@ SK_U32 PortNumber) /* Port Number */ * SK_MC_FILTERING_INEXACT * SK_ADDR_ILLEGAL_PORT */ -int SkAddrGmacMcUpdate( +static int SkAddrGmacMcUpdate( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber) /* Port Number */ @@ -1468,7 +1483,7 @@ int NewPromMode) /* new promiscuous mode */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -int SkAddrXmacPromiscuousChange( +static int SkAddrXmacPromiscuousChange( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* port whose promiscuous mode changes */ @@ -1585,7 +1600,7 @@ int NewPromMode) /* new promiscuous mode */ * SK_ADDR_SUCCESS * SK_ADDR_ILLEGAL_PORT */ -int SkAddrGmacPromiscuousChange( +static int SkAddrGmacPromiscuousChange( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* I/O context */ SK_U32 PortNumber, /* port whose promiscuous mode changes */ diff --git a/trunk/drivers/net/sk98lin/skgeinit.c b/trunk/drivers/net/sk98lin/skgeinit.c index 6cb49dd02251..67f1d6a5c15d 100644 --- a/trunk/drivers/net/sk98lin/skgeinit.c +++ b/trunk/drivers/net/sk98lin/skgeinit.c @@ -57,34 +57,6 @@ static struct s_Config OemConfig = { #endif }; -/****************************************************************************** - * - * SkGePollRxD() - Enable / Disable Descriptor Polling of RxD Ring - * - * Description: - * Enable or disable the descriptor polling of the receive descriptor - * ring (RxD) for port 'Port'. - * The new configuration is *not* saved over any SkGeStopPort() and - * SkGeInitPort() calls. - * - * Returns: - * nothing - */ -void SkGePollRxD( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -SK_BOOL PollRxD) /* SK_TRUE (enable pol.), SK_FALSE (disable pol.) */ -{ - SK_GEPORT *pPrt; - - pPrt = &pAC->GIni.GP[Port]; - - SK_OUT32(IoC, Q_ADDR(pPrt->PRxQOff, Q_CSR), (PollRxD) ? - CSR_ENA_POL : CSR_DIS_POL); -} /* SkGePollRxD */ - - /****************************************************************************** * * SkGePollTxD() - Enable / Disable Descriptor Polling of TxD Rings @@ -952,7 +924,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -void SkGeInitRamIface( +static void SkGeInitRamIface( SK_AC *pAC, /* adapter context */ SK_IOC IoC) /* IO context */ { @@ -1409,83 +1381,6 @@ SK_IOC IoC) /* IO context */ } /* SkGeInit0*/ -#ifdef SK_PCI_RESET - -/****************************************************************************** - * - * SkGePciReset() - Reset PCI interface - * - * Description: - * o Read PCI configuration. - * o Change power state to 3. - * o Change power state to 0. - * o Restore PCI configuration. - * - * Returns: - * 0: Success. - * 1: Power state could not be changed to 3. - */ -static int SkGePciReset( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC) /* IO context */ -{ - int i; - SK_U16 PmCtlSts; - SK_U32 Bp1; - SK_U32 Bp2; - SK_U16 PciCmd; - SK_U8 Cls; - SK_U8 Lat; - SK_U8 ConfigSpace[PCI_CFG_SIZE]; - - /* - * Note: Switching to D3 state is like a software reset. - * Switching from D3 to D0 is a hardware reset. - * We have to save and restore the configuration space. - */ - for (i = 0; i < PCI_CFG_SIZE; i++) { - SkPciReadCfgDWord(pAC, i*4, &ConfigSpace[i]); - } - - /* We know the RAM Interface Arbiter is enabled. */ - SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D3); - SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); - - if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D3) { - return(1); - } - - /* Return to D0 state. */ - SkPciWriteCfgWord(pAC, PCI_PM_CTL_STS, PCI_PM_STATE_D0); - - /* Check for D0 state. */ - SkPciReadCfgWord(pAC, PCI_PM_CTL_STS, &PmCtlSts); - - if ((PmCtlSts & PCI_PM_STATE_MSK) != PCI_PM_STATE_D0) { - return(1); - } - - /* Check PCI Config Registers. */ - SkPciReadCfgWord(pAC, PCI_COMMAND, &PciCmd); - SkPciReadCfgByte(pAC, PCI_CACHE_LSZ, &Cls); - SkPciReadCfgDWord(pAC, PCI_BASE_1ST, &Bp1); - SkPciReadCfgDWord(pAC, PCI_BASE_2ND, &Bp2); - SkPciReadCfgByte(pAC, PCI_LAT_TIM, &Lat); - - if (PciCmd != 0 || Cls != (SK_U8)0 || Lat != (SK_U8)0 || - (Bp1 & 0xfffffff0L) != 0 || Bp2 != 1) { - return(1); - } - - /* Restore PCI Config Space. */ - for (i = 0; i < PCI_CFG_SIZE; i++) { - SkPciWriteCfgDWord(pAC, i*4, ConfigSpace[i]); - } - - return(0); -} /* SkGePciReset */ - -#endif /* SK_PCI_RESET */ /****************************************************************************** * @@ -1524,10 +1419,6 @@ SK_IOC IoC) /* IO context */ /* save CLK_RUN bits (YUKON-Lite) */ SK_IN16(IoC, B0_CTST, &CtrlStat); -#ifdef SK_PCI_RESET - (void)SkGePciReset(pAC, IoC); -#endif /* SK_PCI_RESET */ - /* do the SW-reset */ SK_OUT8(IoC, B0_CTST, CS_RST_SET); @@ -1991,11 +1882,6 @@ SK_IOC IoC) /* IO context */ int i; SK_U16 Word; -#ifdef SK_PHY_LP_MODE - SK_U8 Byte; - SK_U16 PmCtlSts; -#endif /* SK_PHY_LP_MODE */ - #if (!defined(SK_SLIM) && !defined(VCPU)) /* ensure I2C is ready */ SkI2cWaitIrq(pAC, IoC); @@ -2010,38 +1896,6 @@ SK_IOC IoC) /* IO context */ } } -#ifdef SK_PHY_LP_MODE - /* - * for power saving purposes within mobile environments - * we set the PHY to coma mode and switch to D3 power state. - */ - if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { - - /* for all ports switch PHY to coma mode */ - for (i = 0; i < pAC->GIni.GIMacsFound; i++) { - - SkGmEnterLowPowerMode(pAC, IoC, i, PHY_PM_DEEP_SLEEP); - } - - if (pAC->GIni.GIVauxAvail) { - /* switch power to VAUX */ - Byte = PC_VAUX_ENA | PC_VCC_ENA | PC_VAUX_ON | PC_VCC_OFF; - - SK_OUT8(IoC, B0_POWER_CTRL, Byte); - } - - /* switch to D3 state */ - SK_IN16(IoC, PCI_C(PCI_PM_CTL_STS), &PmCtlSts); - - PmCtlSts |= PCI_PM_STATE_D3; - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - - SK_OUT16(IoC, PCI_C(PCI_PM_CTL_STS), PmCtlSts); - } -#endif /* SK_PHY_LP_MODE */ - /* Reset all bits in the PCI STATUS register */ /* * Note: PCI Cfg cycles cannot be used, because they are not diff --git a/trunk/drivers/net/sk98lin/skgemib.c b/trunk/drivers/net/sk98lin/skgemib.c index 2991bc85cf2c..0a6f67a7a395 100644 --- a/trunk/drivers/net/sk98lin/skgemib.c +++ b/trunk/drivers/net/sk98lin/skgemib.c @@ -871,13 +871,6 @@ PNMI_STATIC const SK_PNMI_TAB_ENTRY IdTable[] = { sizeof(SK_PNMI_CONF), SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyType), SK_PNMI_RO, MacPrivateConf, 0}, -#ifdef SK_PHY_LP_MODE - {OID_SKGE_PHY_LP_MODE, - SK_PNMI_MAC_ENTRIES, - sizeof(SK_PNMI_CONF), - SK_PNMI_OFF(Conf) + SK_PNMI_CNF_OFF(ConfPhyMode), - SK_PNMI_RW, MacPrivateConf, 0}, -#endif {OID_SKGE_LINK_CAP, SK_PNMI_MAC_ENTRIES, sizeof(SK_PNMI_CONF), diff --git a/trunk/drivers/net/sk98lin/skgepnmi.c b/trunk/drivers/net/sk98lin/skgepnmi.c index a386172107e8..b36dd9ac6b29 100644 --- a/trunk/drivers/net/sk98lin/skgepnmi.c +++ b/trunk/drivers/net/sk98lin/skgepnmi.c @@ -56,10 +56,6 @@ static const char SysKonnectFileId[] = * Public Function prototypes */ int SkPnmiInit(SK_AC *pAC, SK_IOC IoC, int level); -int SkPnmiGetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, - unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); -int SkPnmiPreSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, - unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); int SkPnmiSetVar(SK_AC *pAC, SK_IOC IoC, SK_U32 Id, void *pBuf, unsigned int *pLen, SK_U32 Instance, SK_U32 NetIndex); int SkPnmiGetStruct(SK_AC *pAC, SK_IOC IoC, void *pBuf, @@ -587,7 +583,7 @@ int Level) /* Initialization level */ * exist (e.g. port instance 3 on a two port * adapter. */ -int SkPnmiGetVar( +static int SkPnmiGetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ @@ -629,7 +625,7 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ * exist (e.g. port instance 3 on a two port * adapter. */ -int SkPnmiPreSetVar( +static int SkPnmiPreSetVar( SK_AC *pAC, /* Pointer to adapter context */ SK_IOC IoC, /* IO context handle */ SK_U32 Id, /* Object ID that is to be processed */ @@ -5062,9 +5058,6 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ case OID_SKGE_SPEED_CAP: case OID_SKGE_SPEED_MODE: case OID_SKGE_SPEED_STATUS: -#ifdef SK_PHY_LP_MODE - case OID_SKGE_PHY_LP_MODE: -#endif if (*pLen < (Limit - LogPortIndex) * sizeof(SK_U8)) { *pLen = (Limit - LogPortIndex) * sizeof(SK_U8); @@ -5140,28 +5133,6 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ Offset += sizeof(SK_U32); break; -#ifdef SK_PHY_LP_MODE - case OID_SKGE_PHY_LP_MODE: - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - continue; - } - else { - /* Get value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); - Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; - *pBufPtr = Val8; - } - } - else { /* DualNetMode */ - - Val8 = (SK_U8) pAC->GIni.GP[PhysPortIndex].PPhyPowerState; - *pBufPtr = Val8; - } - Offset += sizeof(SK_U8); - break; -#endif - case OID_SKGE_LINK_CAP: if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ if (LogPortIndex == 0) { @@ -5478,16 +5449,6 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ } break; -#ifdef SK_PHY_LP_MODE - case OID_SKGE_PHY_LP_MODE: - if (*pLen < Limit - LogPortIndex) { - - *pLen = Limit - LogPortIndex; - return (SK_PNMI_ERR_TOO_SHORT); - } - break; -#endif - case OID_SKGE_MTU: if (*pLen < sizeof(SK_U32)) { @@ -5845,116 +5806,6 @@ SK_U32 NetIndex) /* NetIndex (0..n), in single net mode always zero */ Offset += sizeof(SK_U32); break; -#ifdef SK_PHY_LP_MODE - case OID_SKGE_PHY_LP_MODE: - /* The preset ends here */ - if (Action == SK_PNMI_PRESET) { - - return (SK_PNMI_ERR_OK); - } - - if (!pAC->Pnmi.DualNetActiveFlag) { /* SingleNetMode */ - if (LogPortIndex == 0) { - Offset = 0; - continue; - } - else { - /* Set value for physical ports */ - PhysPortIndex = SK_PNMI_PORT_LOG2PHYS(pAC, LogPortIndex); - - switch (*(pBuf + Offset)) { - case 0: - /* If LowPowerMode is active, we can leave it. */ - if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { - - Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); - - if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { - - SkDrvInitAdapter(pAC); - } - break; - } - else { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - case 1: - case 2: - case 3: - case 4: - /* If no LowPowerMode is active, we can enter it. */ - if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { - - if ((*(pBuf + Offset)) < 3) { - - SkDrvDeInitAdapter(pAC); - } - - Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); - break; - } - else { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - default: - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - } - } - else { /* DualNetMode */ - - switch (*(pBuf + Offset)) { - case 0: - /* If we are in a LowPowerMode, we can leave it. */ - if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { - - Val32 = SkGmLeaveLowPowerMode(pAC, IoC, PhysPortIndex); - - if (pAC->GIni.GP[PhysPortIndex].PPhyPowerState < 3) { - - SkDrvInitAdapter(pAC); - } - break; - } - else { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - case 1: - case 2: - case 3: - case 4: - /* If we are not already in LowPowerMode, we can enter it. */ - if (!pAC->GIni.GP[PhysPortIndex].PPhyPowerState) { - - if ((*(pBuf + Offset)) < 3) { - - SkDrvDeInitAdapter(pAC); - } - else { - - Val32 = SkGmEnterLowPowerMode(pAC, IoC, PhysPortIndex, *pBuf); - } - break; - } - else { - *pLen = 0; - return (SK_PNMI_ERR_GENERAL); - } - - default: - *pLen = 0; - return (SK_PNMI_ERR_BAD_VALUE); - } - } - Offset += sizeof(SK_U8); - break; -#endif - default: SK_DBG_MSG(pAC, SK_DBGMOD_PNMI, SK_DBGCAT_ERR, ("MacPrivateConf: Unknown OID should be handled before set")); diff --git a/trunk/drivers/net/sk98lin/skgesirq.c b/trunk/drivers/net/sk98lin/skgesirq.c index 87520f0057d7..ab66d80a4455 100644 --- a/trunk/drivers/net/sk98lin/skgesirq.c +++ b/trunk/drivers/net/sk98lin/skgesirq.c @@ -265,7 +265,7 @@ int Port) /* Port Index (MAC_1 + n) */ * * Returns: N/A */ -void SkHWLinkUp( +static void SkHWLinkUp( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -612,14 +612,6 @@ SK_U32 Istatus) /* Interrupt status word */ * we ignore those */ pPrt->HalfDupTimerActive = SK_TRUE; -#ifdef XXX - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 0), - pAC->Rlmt.Port[0].Net->NetNumber); - - pPrt->LastOctets = Octets; -#endif /* XXX */ /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, 0); @@ -653,14 +645,6 @@ SK_U32 Istatus) /* Interrupt status word */ pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) && !pPrt->HalfDupTimerActive) { pPrt->HalfDupTimerActive = SK_TRUE; -#ifdef XXX - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, 1), - pAC->Rlmt.Port[1].Net->NetNumber); - - pPrt->LastOctets = Octets; -#endif /* XXX */ /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, 1); @@ -2085,12 +2069,6 @@ SK_EVPARA Para) /* Event specific Parameter */ pPrt->HalfDupTimerActive = SK_FALSE; if (pPrt->PLinkModeStatus == SK_LMODE_STAT_HALF || pPrt->PLinkModeStatus == SK_LMODE_STAT_AUTOHALF) { -#ifdef XXX - Len = sizeof(SK_U64); - SkPnmiGetVar(pAC, IoC, OID_SKGE_STAT_TX_OCTETS, (char *)&Octets, - &Len, (SK_U32)SK_PNMI_PORT_PHYS2INST(pAC, Port), - pAC->Rlmt.Port[Port].Net->NetNumber); -#endif /* XXX */ /* Snap statistic counters */ (void)SkXmUpdateStats(pAC, IoC, Port); diff --git a/trunk/drivers/net/sk98lin/ski2c.c b/trunk/drivers/net/sk98lin/ski2c.c index 075a0464e56b..79bf57cb5326 100644 --- a/trunk/drivers/net/sk98lin/ski2c.c +++ b/trunk/drivers/net/sk98lin/ski2c.c @@ -396,7 +396,7 @@ int Rw) /* Read / Write Flag */ * 1: error, transfer does not complete, I2C transfer * killed, wait loop terminated. */ -int SkI2cWait( +static int SkI2cWait( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ int Event) /* complete event to wait for (I2C_READ or I2C_WRITE) */ @@ -481,7 +481,7 @@ SK_IOC IoC) /* I/O Context */ * returns 0: success * 1: error */ -int SkI2cWrite( +static int SkI2cWrite( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_U32 I2cData, /* I2C Data to write */ @@ -538,7 +538,7 @@ int I2cBurst) /* I2C Burst Flag */ * 1 if the read is completed * 0 if the read must be continued (I2C Bus still allocated) */ -int SkI2cReadSensor( +static int SkI2cReadSensor( SK_AC *pAC, /* Adapter Context */ SK_IOC IoC, /* I/O Context */ SK_SENSOR *pSen) /* Sensor to be read */ diff --git a/trunk/drivers/net/sk98lin/sklm80.c b/trunk/drivers/net/sk98lin/sklm80.c index 68292d18175b..a204f5bb55d4 100644 --- a/trunk/drivers/net/sk98lin/sklm80.c +++ b/trunk/drivers/net/sk98lin/sklm80.c @@ -34,79 +34,7 @@ static const char SysKonnectFileId[] = #include "h/lm80.h" #include "h/skdrv2nd.h" /* Adapter Control- and Driver specific Def. */ -#ifdef SK_DIAG -#define BREAK_OR_WAIT(pAC,IoC,Event) SkI2cWait(pAC,IoC,Event) -#else /* nSK_DIAG */ #define BREAK_OR_WAIT(pAC,IoC,Event) break -#endif /* nSK_DIAG */ - -#ifdef SK_DIAG -/* - * read the register 'Reg' from the device 'Dev' - * - * return read error -1 - * success the read value - */ -int SkLm80RcvReg( -SK_IOC IoC, /* Adapter Context */ -int Dev, /* I2C device address */ -int Reg) /* register to read */ -{ - int Val = 0; - int TempExt; - - /* Signal device number */ - if (SkI2cSndDev(IoC, Dev, I2C_WRITE)) { - return(-1); - } - - if (SkI2cSndByte(IoC, Reg)) { - return(-1); - } - - /* repeat start */ - if (SkI2cSndDev(IoC, Dev, I2C_READ)) { - return(-1); - } - - switch (Reg) { - case LM80_TEMP_IN: - Val = (int)SkI2cRcvByte(IoC, 1); - - /* First: correct the value: it might be negative */ - if ((Val & 0x80) != 0) { - /* Value is negative */ - Val = Val - 256; - } - Val = Val * SK_LM80_TEMP_LSB; - SkI2cStop(IoC); - - TempExt = (int)SkLm80RcvReg(IoC, LM80_ADDR, LM80_TEMP_CTRL); - - if (Val > 0) { - Val += ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); - } - else { - Val -= ((TempExt >> 7) * SK_LM80_TEMPEXT_LSB); - } - return(Val); - break; - case LM80_VT0_IN: - case LM80_VT1_IN: - case LM80_VT2_IN: - case LM80_VT3_IN: - Val = (int)SkI2cRcvByte(IoC, 1) * SK_LM80_VT_LSB; - break; - - default: - Val = (int)SkI2cRcvByte(IoC, 1); - break; - } - - SkI2cStop(IoC); - return(Val); -} -#endif /* SK_DIAG */ /* * read a sensors value (LM80 specific) diff --git a/trunk/drivers/net/sk98lin/skrlmt.c b/trunk/drivers/net/sk98lin/skrlmt.c index 9ea11ab2296a..be8d1ccddf6d 100644 --- a/trunk/drivers/net/sk98lin/skrlmt.c +++ b/trunk/drivers/net/sk98lin/skrlmt.c @@ -282,7 +282,6 @@ typedef struct s_SpTreeRlmtPacket { SK_MAC_ADDR SkRlmtMcAddr = {{0x01, 0x00, 0x5A, 0x52, 0x4C, 0x4D}}; SK_MAC_ADDR BridgeMcAddr = {{0x01, 0x80, 0xC2, 0x00, 0x00, 0x00}}; -SK_MAC_ADDR BcAddr = {{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF}}; /* local variables ************************************************************/ diff --git a/trunk/drivers/net/sk98lin/skvpd.c b/trunk/drivers/net/sk98lin/skvpd.c index eb3c8988ced1..17786056c66a 100644 --- a/trunk/drivers/net/sk98lin/skvpd.c +++ b/trunk/drivers/net/sk98lin/skvpd.c @@ -132,65 +132,6 @@ int addr) /* VPD address */ #endif /* SKDIAG */ -#if 0 - -/* - Write the dword 'data' at address 'addr' into the VPD EEPROM, and - verify that the data is written. - - Needed Time: - -. MIN MAX -. ------------------------------------------------------------------- -. write 1.8 ms 3.6 ms -. internal write cyles 0.7 ms 7.0 ms -. ------------------------------------------------------------------- -. over all program time 2.5 ms 10.6 ms -. read 1.3 ms 2.6 ms -. ------------------------------------------------------------------- -. over all 3.8 ms 13.2 ms -. - - - Returns 0: success - 1: error, I2C transfer does not terminate - 2: error, data verify error - - */ -static int VpdWriteDWord( -SK_AC *pAC, /* pAC pointer */ -SK_IOC IoC, /* IO Context */ -int addr, /* VPD address */ -SK_U32 data) /* VPD data to write */ -{ - /* start VPD write */ - /* Don't swap here, it's a data stream of bytes */ - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_CTRL, - ("VPD write dword at addr 0x%x, data = 0x%x\n",addr,data)); - VPD_OUT32(pAC, IoC, PCI_VPD_DAT_REG, (SK_U32)data); - /* But do it here */ - addr |= VPD_WRITE; - - VPD_OUT16(pAC, IoC, PCI_VPD_ADR_REG, (SK_U16)(addr | VPD_WRITE)); - - /* this may take up to 10,6 ms */ - if (VpdWait(pAC, IoC, VPD_WRITE)) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("Write Timed Out\n")); - return(1); - }; - - /* verify data */ - if (VpdReadDWord(pAC, IoC, addr) != data) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR | SK_DBGCAT_FATAL, - ("Data Verify Error\n")); - return(2); - } - return(0); -} /* VpdWriteDWord */ - -#endif /* 0 */ - /* * Read one Stream of 'len' bytes of VPD data, starting at 'addr' from * or to the I2C EEPROM. @@ -728,7 +669,7 @@ char *etp) /* end pointer input position */ * 6: fatal VPD error * */ -int VpdSetupPara( +static int VpdSetupPara( SK_AC *pAC, /* common data base */ const char *key, /* keyword to insert */ const char *buf, /* buffer with the keyword value */ @@ -1148,50 +1089,3 @@ SK_IOC IoC) /* IO Context */ return(0); } - - -/* - * Read the contents of the VPD EEPROM and copy it to the VPD buffer - * if not already done. If the keyword "VF" is not present it will be - * created and the error log message will be stored to this keyword. - * If "VF" is not present the error log message will be stored to the - * keyword "VL". "VL" will created or overwritten if "VF" is present. - * The VPD read/write area is saved to the VPD EEPROM. - * - * returns nothing, errors will be ignored. - */ -void VpdErrLog( -SK_AC *pAC, /* common data base */ -SK_IOC IoC, /* IO Context */ -char *msg) /* error log message */ -{ - SK_VPD_PARA *v, vf; /* VF */ - int len; - - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, - ("VPD error log msg %s\n", msg)); - if ((pAC->vpd.v.vpd_status & VPD_VALID) == 0) { - if (VpdInit(pAC, IoC) != 0) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_ERR, - ("VPD init error\n")); - return; - } - } - - len = strlen(msg); - if (len > VPD_MAX_LEN) { - /* cut it */ - len = VPD_MAX_LEN; - } - if ((v = vpd_find_para(pAC, VPD_VF, &vf)) != NULL) { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("overwrite VL\n")); - (void)VpdSetupPara(pAC, VPD_VL, msg, len, VPD_RW_KEY, OWR_KEY); - } - else { - SK_DBG_MSG(pAC, SK_DBGMOD_VPD, SK_DBGCAT_TX, ("write VF\n")); - (void)VpdSetupPara(pAC, VPD_VF, msg, len, VPD_RW_KEY, ADD_KEY); - } - - (void)VpdUpdate(pAC, IoC); -} - diff --git a/trunk/drivers/net/sk98lin/skxmac2.c b/trunk/drivers/net/sk98lin/skxmac2.c index 42d2d963150a..b4e75022a657 100644 --- a/trunk/drivers/net/sk98lin/skxmac2.c +++ b/trunk/drivers/net/sk98lin/skxmac2.c @@ -41,13 +41,13 @@ static const char SysKonnectFileId[] = #endif #ifdef GENESIS -BCOM_HACK BcomRegA1Hack[] = { +static BCOM_HACK BcomRegA1Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1104 }, { 0x17, 0x0013 }, { 0x15, 0x0404 }, { 0x17, 0x8006 }, { 0x15, 0x0132 }, { 0x17, 0x8006 }, { 0x15, 0x0232 }, { 0x17, 0x800D }, { 0x15, 0x000F }, { 0x18, 0x0420 }, { 0, 0 } }; -BCOM_HACK BcomRegC0Hack[] = { +static BCOM_HACK BcomRegC0Hack[] = { { 0x18, 0x0c20 }, { 0x17, 0x0012 }, { 0x15, 0x1204 }, { 0x17, 0x0013 }, { 0x15, 0x0A04 }, { 0x18, 0x0420 }, { 0, 0 } @@ -790,7 +790,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -void SkMacFlushRxFifo( +static void SkMacFlushRxFifo( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -1231,38 +1231,6 @@ int Port) /* Port Index (MAC_1 + n) */ } /* SkMacHardRst */ -/****************************************************************************** - * - * SkMacClearRst() - Clear the MAC reset - * - * Description: calls a clear MAC reset routine dep. on board type - * - * Returns: - * nothing - */ -void SkMacClearRst( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (MAC_1 + n) */ -{ - -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - SkXmClearRst(pAC, IoC, Port); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - SkGmClearRst(pAC, IoC, Port); - } -#endif /* YUKON */ - -} /* SkMacClearRst */ - - #ifdef GENESIS /****************************************************************************** * @@ -1713,7 +1681,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -void SkXmInitDupMd( +static void SkXmInitDupMd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -1761,7 +1729,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -void SkXmInitPauseMd( +static void SkXmInitPauseMd( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -2076,283 +2044,7 @@ SK_BOOL DoLoop) /* Should a Phy LoopBack be set-up? */ } /* SkXmInitPhyBcom */ #endif /* GENESIS */ - #ifdef YUKON -#ifndef SK_SLIM -/****************************************************************************** - * - * SkGmEnterLowPowerMode() - * - * Description: - * This function sets the Marvell Alaska PHY to the low power mode - * given by parameter mode. - * The following low power modes are available: - * - * - Coma Mode (Deep Sleep): - * Power consumption: ~15 - 30 mW - * The PHY cannot wake up on its own. - * - * - IEEE 22.2.4.1.5 compatible power down mode - * Power consumption: ~240 mW - * The PHY cannot wake up on its own. - * - * - energy detect mode - * Power consumption: ~160 mW - * The PHY can wake up on its own by detecting activity - * on the CAT 5 cable. - * - * - energy detect plus mode - * Power consumption: ~150 mW - * The PHY can wake up on its own by detecting activity - * on the CAT 5 cable. - * Connected devices can be woken up by sending normal link - * pulses every one second. - * - * Note: - * - * Returns: - * 0: ok - * 1: error - */ -int SkGmEnterLowPowerMode( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (e.g. MAC_1) */ -SK_U8 Mode) /* low power mode */ -{ - SK_U16 Word; - SK_U32 DWord; - SK_U8 LastMode; - int Ret = 0; - - if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { - - /* save current power mode */ - LastMode = pAC->GIni.GP[Port].PPhyPowerState; - pAC->GIni.GP[Port].PPhyPowerState = Mode; - - switch (Mode) { - /* coma mode (deep sleep) */ - case PHY_PM_DEEP_SLEEP: - /* setup General Purpose Control Register */ - GM_OUT16(IoC, 0, GM_GP_CTRL, GM_GPCR_FL_PASS | - GM_GPCR_SPEED_100 | GM_GPCR_AU_ALL_DIS); - - /* apply COMA mode workaround */ - SkGmPhyWrite(pAC, IoC, Port, 29, 0x001f); - SkGmPhyWrite(pAC, IoC, Port, 30, 0xfff3); - - SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - - /* Set PHY to Coma Mode */ - SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord | PCI_PHY_COMA); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - - break; - - /* IEEE 22.2.4.1.5 compatible power down mode */ - case PHY_PM_IEEE_POWER_DOWN: - /* - * - disable MAC 125 MHz clock - * - allow MAC power down - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word |= PHY_M_PC_DIS_125CLK; - Word &= ~PHY_M_PC_MAC_POW_UP; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); - - /* - * register changes must be followed by a software - * reset to take effect - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); - Word |= PHY_CT_RESET; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); - - /* switch IEEE compatible power down mode on */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); - Word |= PHY_CT_PDOWN; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); - break; - - /* energy detect and energy detect plus mode */ - case PHY_PM_ENERGY_DETECT: - case PHY_PM_ENERGY_DETECT_PLUS: - /* - * - disable MAC 125 MHz clock - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word |= PHY_M_PC_DIS_125CLK; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); - - /* activate energy detect mode 1 */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - - /* energy detect mode */ - if (Mode == PHY_PM_ENERGY_DETECT) { - Word |= PHY_M_PC_EN_DET; - } - /* energy detect plus mode */ - else { - Word |= PHY_M_PC_EN_DET_PLUS; - } - - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); - - /* - * reinitialize the PHY to force a software reset - * which is necessary after the register settings - * for the energy detect modes. - * Furthermore reinitialisation prevents that the - * PHY is running out of a stable state. - */ - SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); - break; - - /* don't change current power mode */ - default: - pAC->GIni.GP[Port].PPhyPowerState = LastMode; - Ret = 1; - break; - } - } - /* low power modes are not supported by this chip */ - else { - Ret = 1; - } - - return(Ret); - -} /* SkGmEnterLowPowerMode */ - -/****************************************************************************** - * - * SkGmLeaveLowPowerMode() - * - * Description: - * Leave the current low power mode and switch to normal mode - * - * Note: - * - * Returns: - * 0: ok - * 1: error - */ -int SkGmLeaveLowPowerMode( -SK_AC *pAC, /* adapter context */ -SK_IOC IoC, /* IO context */ -int Port) /* Port Index (e.g. MAC_1) */ -{ - SK_U32 DWord; - SK_U16 Word; - SK_U8 LastMode; - int Ret = 0; - - if (pAC->GIni.GIYukonLite && - pAC->GIni.GIChipRev >= CHIP_REV_YU_LITE_A3) { - - /* save current power mode */ - LastMode = pAC->GIni.GP[Port].PPhyPowerState; - pAC->GIni.GP[Port].PPhyPowerState = PHY_PM_OPERATIONAL_MODE; - - switch (LastMode) { - /* coma mode (deep sleep) */ - case PHY_PM_DEEP_SLEEP: - SK_IN32(IoC, PCI_C(PCI_OUR_REG_1), &DWord); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_ON); - - /* Release PHY from Coma Mode */ - SK_OUT32(IoC, PCI_C(PCI_OUR_REG_1), DWord & ~PCI_PHY_COMA); - - SK_OUT8(IoC, B2_TST_CTRL1, TST_CFG_WRITE_OFF); - - SK_IN32(IoC, B2_GP_IO, &DWord); - - /* set to output */ - DWord |= (GP_DIR_9 | GP_IO_9); - - /* set PHY reset */ - SK_OUT32(IoC, B2_GP_IO, DWord); - - DWord &= ~GP_IO_9; /* clear PHY reset (active high) */ - - /* clear PHY reset */ - SK_OUT32(IoC, B2_GP_IO, DWord); - break; - - /* IEEE 22.2.4.1.5 compatible power down mode */ - case PHY_PM_IEEE_POWER_DOWN: - /* - * - enable MAC 125 MHz clock - * - set MAC power up - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word &= ~PHY_M_PC_DIS_125CLK; - Word |= PHY_M_PC_MAC_POW_UP; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); - - /* - * register changes must be followed by a software - * reset to take effect - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); - Word |= PHY_CT_RESET; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); - - /* switch IEEE compatible power down mode off */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_CTRL, &Word); - Word &= ~PHY_CT_PDOWN; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_CTRL, Word); - break; - - /* energy detect and energy detect plus mode */ - case PHY_PM_ENERGY_DETECT: - case PHY_PM_ENERGY_DETECT_PLUS: - /* - * - enable MAC 125 MHz clock - */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word &= ~PHY_M_PC_DIS_125CLK; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); - - /* disable energy detect mode */ - SkGmPhyRead(pAC, IoC, Port, PHY_MARV_PHY_CTRL, &Word); - Word &= ~PHY_M_PC_EN_DET_MSK; - SkGmPhyWrite(pAC, IoC, Port, PHY_MARV_PHY_CTRL, Word); - - /* - * reinitialize the PHY to force a software reset - * which is necessary after the register settings - * for the energy detect modes. - * Furthermore reinitialisation prevents that the - * PHY is running out of a stable state. - */ - SkGmInitPhyMarv(pAC, IoC, Port, SK_FALSE); - break; - - /* don't change current power mode */ - default: - pAC->GIni.GP[Port].PPhyPowerState = LastMode; - Ret = 1; - break; - } - } - /* low power modes are not supported by this chip */ - else { - Ret = 1; - } - - return(Ret); - -} /* SkGmLeaveLowPowerMode */ -#endif /* !SK_SLIM */ - - /****************************************************************************** * * SkGmInitPhyMarv() - Initialize the Marvell Phy registers @@ -3420,145 +3112,6 @@ int Port) /* Port Index (MAC_1 + n) */ } /* SkMacAutoNegDone */ -#ifdef GENESIS -/****************************************************************************** - * - * SkXmSetRxTxEn() - Special Set Rx/Tx Enable and some features in XMAC - * - * Description: - * sets MAC or PHY LoopBack and Duplex Mode in the MMU Command Reg. - * enables Rx/Tx - * - * Returns: N/A - */ -static void SkXmSetRxTxEn( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -int Para) /* Parameter to set: MAC or PHY LoopBack, Duplex Mode */ -{ - SK_U16 Word; - - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - - switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { - case SK_MAC_LOOPB_ON: - Word |= XM_MMU_MAC_LB; - break; - case SK_MAC_LOOPB_OFF: - Word &= ~XM_MMU_MAC_LB; - break; - } - - switch (Para & (SK_PHY_LOOPB_ON | SK_PHY_LOOPB_OFF)) { - case SK_PHY_LOOPB_ON: - Word |= XM_MMU_GMII_LOOP; - break; - case SK_PHY_LOOPB_OFF: - Word &= ~XM_MMU_GMII_LOOP; - break; - } - - switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { - case SK_PHY_FULLD_ON: - Word |= XM_MMU_GMII_FD; - break; - case SK_PHY_FULLD_OFF: - Word &= ~XM_MMU_GMII_FD; - break; - } - - XM_OUT16(IoC, Port, XM_MMU_CMD, Word | XM_MMU_ENA_RX | XM_MMU_ENA_TX); - - /* dummy read to ensure writing */ - XM_IN16(IoC, Port, XM_MMU_CMD, &Word); - -} /* SkXmSetRxTxEn */ -#endif /* GENESIS */ - - -#ifdef YUKON -/****************************************************************************** - * - * SkGmSetRxTxEn() - Special Set Rx/Tx Enable and some features in GMAC - * - * Description: - * sets MAC LoopBack and Duplex Mode in the General Purpose Control Reg. - * enables Rx/Tx - * - * Returns: N/A - */ -static void SkGmSetRxTxEn( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -int Para) /* Parameter to set: MAC LoopBack, Duplex Mode */ -{ - SK_U16 Ctrl; - - GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); - - switch (Para & (SK_MAC_LOOPB_ON | SK_MAC_LOOPB_OFF)) { - case SK_MAC_LOOPB_ON: - Ctrl |= GM_GPCR_LOOP_ENA; - break; - case SK_MAC_LOOPB_OFF: - Ctrl &= ~GM_GPCR_LOOP_ENA; - break; - } - - switch (Para & (SK_PHY_FULLD_ON | SK_PHY_FULLD_OFF)) { - case SK_PHY_FULLD_ON: - Ctrl |= GM_GPCR_DUP_FULL; - break; - case SK_PHY_FULLD_OFF: - Ctrl &= ~GM_GPCR_DUP_FULL; - break; - } - - GM_OUT16(IoC, Port, GM_GP_CTRL, (SK_U16)(Ctrl | GM_GPCR_RX_ENA | - GM_GPCR_TX_ENA)); - - /* dummy read to ensure writing */ - GM_IN16(IoC, Port, GM_GP_CTRL, &Ctrl); - -} /* SkGmSetRxTxEn */ -#endif /* YUKON */ - - -#ifndef SK_SLIM -/****************************************************************************** - * - * SkMacSetRxTxEn() - Special Set Rx/Tx Enable and parameters - * - * Description: calls the Special Set Rx/Tx Enable routines dep. on board type - * - * Returns: N/A - */ -void SkMacSetRxTxEn( -SK_AC *pAC, /* Adapter Context */ -SK_IOC IoC, /* IO context */ -int Port, /* Port Index (MAC_1 + n) */ -int Para) -{ -#ifdef GENESIS - if (pAC->GIni.GIGenesis) { - - SkXmSetRxTxEn(pAC, IoC, Port, Para); - } -#endif /* GENESIS */ - -#ifdef YUKON - if (pAC->GIni.GIYukon) { - - SkGmSetRxTxEn(pAC, IoC, Port, Para); - } -#endif /* YUKON */ - -} /* SkMacSetRxTxEn */ -#endif /* !SK_SLIM */ - - /****************************************************************************** * * SkMacRxTxEnable() - Enable Rx/Tx activity if port is up @@ -3976,7 +3529,7 @@ SK_U16 PhyStat) /* PHY Status word to analyse */ * Returns: * nothing */ -void SkXmIrq( +static void SkXmIrq( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ @@ -4112,7 +3665,7 @@ int Port) /* Port Index (MAC_1 + n) */ * Returns: * nothing */ -void SkGmIrq( +static void SkGmIrq( SK_AC *pAC, /* adapter context */ SK_IOC IoC, /* IO context */ int Port) /* Port Index (MAC_1 + n) */ diff --git a/trunk/drivers/net/spider_net.c b/trunk/drivers/net/spider_net.c index 1f5975a61e1f..0d765f1733b5 100644 --- a/trunk/drivers/net/spider_net.c +++ b/trunk/drivers/net/spider_net.c @@ -22,6 +22,7 @@ */ #include + #include #include #include @@ -29,7 +30,6 @@ #include #include #include -#include #include #include #include @@ -43,7 +43,6 @@ #include #include #include -#include #include #include #include @@ -109,6 +108,42 @@ spider_net_write_reg(struct spider_net_card *card, u32 reg, u32 value) writel(value, card->regs + reg); } +/** + * spider_net_write_reg_sync - writes to an SMMIO register of a card + * @card: device structure + * @reg: register to write to + * @value: value to write into the specified SMMIO register + * + * Unlike spider_net_write_reg, this will also make sure the + * data arrives on the card by reading the reg again. + */ +static void +spider_net_write_reg_sync(struct spider_net_card *card, u32 reg, u32 value) +{ + value = cpu_to_le32(value); + writel(value, card->regs + reg); + (void)readl(card->regs + reg); +} + +/** + * spider_net_rx_irq_off - switch off rx irq on this spider card + * @card: device structure + * + * switches off rx irq by masking them out in the GHIINTnMSK register + */ +static void +spider_net_rx_irq_off(struct spider_net_card *card) +{ + u32 regvalue; + unsigned long flags; + + spin_lock_irqsave(&card->intmask_lock, flags); + regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); + regvalue &= ~SPIDER_NET_RXINT; + spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); + spin_unlock_irqrestore(&card->intmask_lock, flags); +} + /** spider_net_write_phy - write to phy register * @netdev: adapter to be written to * @mii_id: id of MII @@ -164,33 +199,60 @@ spider_net_read_phy(struct net_device *netdev, int mii_id, int reg) } /** - * spider_net_rx_irq_off - switch off rx irq on this spider card + * spider_net_rx_irq_on - switch on rx irq on this spider card * @card: device structure * - * switches off rx irq by masking them out in the GHIINTnMSK register + * switches on rx irq by enabling them in the GHIINTnMSK register */ static void -spider_net_rx_irq_off(struct spider_net_card *card) +spider_net_rx_irq_on(struct spider_net_card *card) { u32 regvalue; + unsigned long flags; - regvalue = SPIDER_NET_INT0_MASK_VALUE & (~SPIDER_NET_RXINT); - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); + spin_lock_irqsave(&card->intmask_lock, flags); + regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); + regvalue |= SPIDER_NET_RXINT; + spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); + spin_unlock_irqrestore(&card->intmask_lock, flags); } /** - * spider_net_rx_irq_on - switch on rx irq on this spider card + * spider_net_tx_irq_off - switch off tx irq on this spider card * @card: device structure * - * switches on rx irq by enabling them in the GHIINTnMSK register + * switches off tx irq by masking them out in the GHIINTnMSK register */ static void -spider_net_rx_irq_on(struct spider_net_card *card) +spider_net_tx_irq_off(struct spider_net_card *card) { u32 regvalue; + unsigned long flags; - regvalue = SPIDER_NET_INT0_MASK_VALUE | SPIDER_NET_RXINT; - spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, regvalue); + spin_lock_irqsave(&card->intmask_lock, flags); + regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); + regvalue &= ~SPIDER_NET_TXINT; + spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); + spin_unlock_irqrestore(&card->intmask_lock, flags); +} + +/** + * spider_net_tx_irq_on - switch on tx irq on this spider card + * @card: device structure + * + * switches on tx irq by enabling them in the GHIINTnMSK register + */ +static void +spider_net_tx_irq_on(struct spider_net_card *card) +{ + u32 regvalue; + unsigned long flags; + + spin_lock_irqsave(&card->intmask_lock, flags); + regvalue = spider_net_read_reg(card, SPIDER_NET_GHIINT0MSK); + regvalue |= SPIDER_NET_TXINT; + spider_net_write_reg_sync(card, SPIDER_NET_GHIINT0MSK, regvalue); + spin_unlock_irqrestore(&card->intmask_lock, flags); } /** @@ -264,8 +326,9 @@ static enum spider_net_descr_status spider_net_get_descr_status(struct spider_net_descr *descr) { u32 cmd_status; - + rmb(); cmd_status = descr->dmac_cmd_status; + rmb(); cmd_status >>= SPIDER_NET_DESCR_IND_PROC_SHIFT; /* no need to mask out any bits, as cmd_status is 32 bits wide only * (and unsigned) */ @@ -286,6 +349,7 @@ spider_net_set_descr_status(struct spider_net_descr *descr, { u32 cmd_status; /* read the status */ + mb(); cmd_status = descr->dmac_cmd_status; /* clean the upper 4 bits */ cmd_status &= SPIDER_NET_DESCR_IND_PROC_MASKO; @@ -293,6 +357,7 @@ spider_net_set_descr_status(struct spider_net_descr *descr, cmd_status |= ((u32)status)<dmac_cmd_status = cmd_status; + wmb(); } /** @@ -333,9 +398,8 @@ spider_net_init_chain(struct spider_net_card *card, { int i; struct spider_net_descr *descr; - dma_addr_t buf; - atomic_set(&card->rx_chain_refill,0); + spin_lock_init(&card->chain_lock); descr = start_descr; memset(descr, 0, sizeof(*descr) * no); @@ -344,14 +408,14 @@ spider_net_init_chain(struct spider_net_card *card, for (i=0; ipdev, descr, - SPIDER_NET_DESCR_SIZE, - PCI_DMA_BIDIRECTIONAL); + descr->bus_addr = + pci_map_single(card->pdev, descr, + SPIDER_NET_DESCR_SIZE, + PCI_DMA_BIDIRECTIONAL); - if (buf == DMA_ERROR_CODE) + if (descr->bus_addr == DMA_ERROR_CODE) goto iommu_error; - descr->bus_addr = buf; descr->next = descr + 1; descr->prev = descr - 1; @@ -375,8 +439,7 @@ spider_net_init_chain(struct spider_net_card *card, for (i=0; i < no; i++, descr++) if (descr->bus_addr) pci_unmap_single(card->pdev, descr->bus_addr, - SPIDER_NET_DESCR_SIZE, - PCI_DMA_BIDIRECTIONAL); + SPIDER_NET_DESCR_SIZE, PCI_DMA_BIDIRECTIONAL); return -ENOMEM; } @@ -396,7 +459,7 @@ spider_net_free_rx_chain_contents(struct spider_net_card *card) if (descr->skb) { dev_kfree_skb(descr->skb); pci_unmap_single(card->pdev, descr->buf_addr, - SPIDER_NET_MAX_FRAME, + SPIDER_NET_MAX_MTU, PCI_DMA_BIDIRECTIONAL); } descr = descr->next; @@ -417,13 +480,12 @@ static int spider_net_prepare_rx_descr(struct spider_net_card *card, struct spider_net_descr *descr) { - dma_addr_t buf; int error = 0; int offset; int bufsize; /* we need to round up the buffer size to a multiple of 128 */ - bufsize = (SPIDER_NET_MAX_FRAME + SPIDER_NET_RXBUF_ALIGN - 1) & + bufsize = (SPIDER_NET_MAX_MTU + SPIDER_NET_RXBUF_ALIGN - 1) & (~(SPIDER_NET_RXBUF_ALIGN - 1)); /* and we need to have it 128 byte aligned, therefore we allocate a @@ -431,8 +493,10 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, /* allocate an skb */ descr->skb = dev_alloc_skb(bufsize + SPIDER_NET_RXBUF_ALIGN - 1); if (!descr->skb) { - if (netif_msg_rx_err(card) && net_ratelimit()) - pr_err("Not enough memory to allocate rx buffer\n"); + if (net_ratelimit()) + if (netif_msg_rx_err(card)) + pr_err("Not enough memory to allocate " + "rx buffer\n"); return -ENOMEM; } descr->buf_size = bufsize; @@ -446,12 +510,12 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, if (offset) skb_reserve(descr->skb, SPIDER_NET_RXBUF_ALIGN - offset); /* io-mmu-map the skb */ - buf = pci_map_single(card->pdev, descr->skb->data, - SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL); - descr->buf_addr = buf; - if (buf == DMA_ERROR_CODE) { + descr->buf_addr = pci_map_single(card->pdev, descr->skb->data, + SPIDER_NET_MAX_MTU, + PCI_DMA_BIDIRECTIONAL); + if (descr->buf_addr == DMA_ERROR_CODE) { dev_kfree_skb_any(descr->skb); - if (netif_msg_rx_err(card) && net_ratelimit()) + if (netif_msg_rx_err(card)) pr_err("Could not iommu-map rx buffer\n"); spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); } else { @@ -462,10 +526,10 @@ spider_net_prepare_rx_descr(struct spider_net_card *card, } /** - * spider_net_enable_rxchtails - sets RX dmac chain tail addresses + * spider_net_enable_rxctails - sets RX dmac chain tail addresses * @card: card structure * - * spider_net_enable_rxchtails sets the RX DMAC chain tail adresses in the + * spider_net_enable_rxctails sets the RX DMAC chain tail adresses in the * chip by writing to the appropriate register. DMA is enabled in * spider_net_enable_rxdmac. */ @@ -487,7 +551,6 @@ spider_net_enable_rxchtails(struct spider_net_card *card) static void spider_net_enable_rxdmac(struct spider_net_card *card) { - wmb(); spider_net_write_reg(card, SPIDER_NET_GDADMACCNTR, SPIDER_NET_DMA_RX_VALUE); } @@ -496,28 +559,32 @@ spider_net_enable_rxdmac(struct spider_net_card *card) * spider_net_refill_rx_chain - refills descriptors/skbs in the rx chains * @card: card structure * - * refills descriptors in the rx chain: allocates skbs and iommu-maps them. + * refills descriptors in all chains (last used chain first): allocates skbs + * and iommu-maps them. */ static void spider_net_refill_rx_chain(struct spider_net_card *card) { struct spider_net_descr_chain *chain; + int count = 0; + unsigned long flags; chain = &card->rx_chain; - /* one context doing the refill (and a second context seeing that - * and omitting it) is ok. If called by NAPI, we'll be called again - * as spider_net_decode_one_descr is called several times. If some - * interrupt calls us, the NAPI is about to clean up anyway. */ - if (atomic_inc_return(&card->rx_chain_refill) == 1) - while (spider_net_get_descr_status(chain->head) == - SPIDER_NET_DESCR_NOT_IN_USE) { - if (spider_net_prepare_rx_descr(card, chain->head)) - break; - chain->head = chain->head->next; - } + spin_lock_irqsave(&card->chain_lock, flags); + while (spider_net_get_descr_status(chain->head) == + SPIDER_NET_DESCR_NOT_IN_USE) { + if (spider_net_prepare_rx_descr(card, chain->head)) + break; + count++; + chain->head = chain->head->next; + } + spin_unlock_irqrestore(&card->chain_lock, flags); - atomic_dec(&card->rx_chain_refill); + /* could be optimized, only do that, if we know the DMA processing + * has terminated */ + if (count) + spider_net_enable_rxdmac(card); } /** @@ -546,7 +613,6 @@ spider_net_alloc_rx_skbs(struct spider_net_card *card) /* this will allocate the rest of the rx buffers; if not, it's * business as usual later on */ spider_net_refill_rx_chain(card); - spider_net_enable_rxdmac(card); return 0; error: @@ -583,30 +649,24 @@ spider_net_release_tx_descr(struct spider_net_card *card, * @card: adapter structure * @brutal: if set, don't care about whether descriptor seems to be in use * - * returns 0 if the tx ring is empty, otherwise 1. - * - * spider_net_release_tx_chain releases the tx descriptors that spider has - * finished with (if non-brutal) or simply release tx descriptors (if brutal). - * If some other context is calling this function, we return 1 so that we're - * scheduled again (if we were scheduled) and will not loose initiative. + * releases the tx descriptors that spider has finished with (if non-brutal) + * or simply release tx descriptors (if brutal) */ -static int +static void spider_net_release_tx_chain(struct spider_net_card *card, int brutal) { struct spider_net_descr_chain *tx_chain = &card->tx_chain; enum spider_net_descr_status status; - if (atomic_inc_return(&card->tx_chain_release) != 1) { - atomic_dec(&card->tx_chain_release); - return 1; - } + spider_net_tx_irq_off(card); + /* no lock for chain needed, if this is only executed once at a time */ +again: for (;;) { status = spider_net_get_descr_status(tx_chain->tail); switch (status) { case SPIDER_NET_DESCR_CARDOWNED: - if (!brutal) - goto out; + if (!brutal) goto out; /* fallthrough, if we release the descriptors * brutally (then we don't care about * SPIDER_NET_DESCR_CARDOWNED) */ @@ -633,30 +693,25 @@ spider_net_release_tx_chain(struct spider_net_card *card, int brutal) tx_chain->tail = tx_chain->tail->next; } out: - atomic_dec(&card->tx_chain_release); - netif_wake_queue(card->netdev); - if (status == SPIDER_NET_DESCR_CARDOWNED) - return 1; - return 0; -} - -/** - * spider_net_cleanup_tx_ring - cleans up the TX ring - * @card: card structure - * - * spider_net_cleanup_tx_ring is called by the tx_timer (as we don't use - * interrupts to cleanup our TX ring) and returns sent packets to the stack - * by freeing them - */ -static void -spider_net_cleanup_tx_ring(struct spider_net_card *card) -{ - if ( (spider_net_release_tx_chain(card, 0)) && - (card->netdev->flags & IFF_UP) ) { - mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); + if (!brutal) { + /* switch on tx irqs (while we are still in the interrupt + * handler, so we don't get an interrupt), check again + * for done descriptors. This results in fewer interrupts */ + spider_net_tx_irq_on(card); + status = spider_net_get_descr_status(tx_chain->tail); + switch (status) { + case SPIDER_NET_DESCR_RESPONSE_ERROR: + case SPIDER_NET_DESCR_PROTECTION_ERROR: + case SPIDER_NET_DESCR_FORCE_END: + case SPIDER_NET_DESCR_COMPLETE: + goto again; + default: + break; + } } + } /** @@ -671,22 +726,16 @@ spider_net_cleanup_tx_ring(struct spider_net_card *card) static u8 spider_net_get_multicast_hash(struct net_device *netdev, __u8 *addr) { + /* FIXME: an addr of 01:00:5e:00:00:01 must result in 0xa9, + * ff:ff:ff:ff:ff:ff must result in 0xfd */ u32 crc; u8 hash; - char addr_for_crc[ETH_ALEN] = { 0, }; - int i, bit; - for (i = 0; i < ETH_ALEN * 8; i++) { - bit = (addr[i / 8] >> (i % 8)) & 1; - addr_for_crc[ETH_ALEN - 1 - i / 8] += bit << (7 - (i % 8)); - } - - crc = crc32_be(~0, addr_for_crc, netdev->addr_len); + crc = crc32_be(~0, addr, netdev->addr_len); hash = (crc >> 27); hash <<= 3; hash |= crc & 7; - hash &= 0xff; return hash; } @@ -772,11 +821,9 @@ spider_net_stop(struct net_device *netdev) { struct spider_net_card *card = netdev_priv(netdev); - tasklet_kill(&card->rxram_full_tl); netif_poll_disable(netdev); netif_carrier_off(netdev); netif_stop_queue(netdev); - del_timer_sync(&card->tx_timer); /* disable/mask all interrupts */ spider_net_write_reg(card, SPIDER_NET_GHIINT0MSK, 0); @@ -825,15 +872,13 @@ spider_net_get_next_tx_descr(struct spider_net_card *card) * @skb: packet to consider * * fills out the command and status field of the descriptor structure, - * depending on hardware checksum settings. + * depending on hardware checksum settings. This function assumes a wmb() + * has executed before. */ static void spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr, struct sk_buff *skb) { - /* make sure the other fields in the descriptor are written */ - wmb(); - if (skb->ip_summed != CHECKSUM_HW) { descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; return; @@ -842,13 +887,14 @@ spider_net_set_txdescr_cmdstat(struct spider_net_descr *descr, /* is packet ip? * if yes: tcp? udp? */ if (skb->protocol == htons(ETH_P_IP)) { - if (skb->nh.iph->protocol == IPPROTO_TCP) + if (skb->nh.iph->protocol == IPPROTO_TCP) { descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_TCPCS; - else if (skb->nh.iph->protocol == IPPROTO_UDP) + } else if (skb->nh.iph->protocol == IPPROTO_UDP) { descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_UDPCS; - else /* the stack should checksum non-tcp and non-udp - packets on his own: NETIF_F_IP_CSUM */ + } else { /* the stack should checksum non-tcp and non-udp + packets on his own: NETIF_F_IP_CSUM */ descr->dmac_cmd_status = SPIDER_NET_DMAC_CMDSTAT_NOCS; + } } } @@ -868,22 +914,23 @@ spider_net_prepare_tx_descr(struct spider_net_card *card, struct spider_net_descr *descr, struct sk_buff *skb) { - dma_addr_t buf; - - buf = pci_map_single(card->pdev, skb->data, - skb->len, PCI_DMA_BIDIRECTIONAL); - if (buf == DMA_ERROR_CODE) { - if (netif_msg_tx_err(card) && net_ratelimit()) + descr->buf_addr = pci_map_single(card->pdev, skb->data, + skb->len, PCI_DMA_BIDIRECTIONAL); + if (descr->buf_addr == DMA_ERROR_CODE) { + if (netif_msg_tx_err(card)) pr_err("could not iommu-map packet (%p, %i). " "Dropping packet\n", skb->data, skb->len); return -ENOMEM; } - descr->buf_addr = buf; descr->buf_size = skb->len; descr->skb = skb; descr->data_status = 0; + /* make sure the above values are in memory before we change the + * status */ + wmb(); + spider_net_set_txdescr_cmdstat(descr,skb); return 0; @@ -925,12 +972,17 @@ spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) struct spider_net_descr *descr; int result; - spider_net_release_tx_chain(card, 0); - descr = spider_net_get_next_tx_descr(card); - if (!descr) - goto error; + if (!descr) { + netif_stop_queue(netdev); + + descr = spider_net_get_next_tx_descr(card); + if (!descr) + goto error; + else + netif_start_queue(netdev); + } result = spider_net_prepare_tx_descr(card, descr, skb); if (result) @@ -938,25 +990,19 @@ spider_net_xmit(struct sk_buff *skb, struct net_device *netdev) card->tx_chain.head = card->tx_chain.head->next; - if (spider_net_get_descr_status(descr->prev) != - SPIDER_NET_DESCR_CARDOWNED) { - /* make sure the current descriptor is in memory. Then - * kicking it on again makes sense, if the previous is not - * card-owned anymore. Check the previous descriptor twice - * to omit an mb() in heavy traffic cases */ - mb(); - if (spider_net_get_descr_status(descr->prev) != - SPIDER_NET_DESCR_CARDOWNED) - spider_net_kick_tx_dma(card, descr); - } + /* make sure the status from spider_net_prepare_tx_descr is in + * memory before we check out the previous descriptor */ + wmb(); - mod_timer(&card->tx_timer, jiffies + SPIDER_NET_TX_TIMER); + if (spider_net_get_descr_status(descr->prev) != + SPIDER_NET_DESCR_CARDOWNED) + spider_net_kick_tx_dma(card, descr); return NETDEV_TX_OK; error: card->netdev_stats.tx_dropped++; - return NETDEV_TX_BUSY; + return NETDEV_TX_LOCKED; } /** @@ -981,7 +1027,6 @@ spider_net_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) * spider_net_pass_skb_up - takes an skb from a descriptor and passes it on * @descr: descriptor to process * @card: card structure - * @napi: whether caller is in NAPI context * * returns 1 on success, 0 if no packet was passed to the stack * @@ -990,7 +1035,7 @@ spider_net_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd) */ static int spider_net_pass_skb_up(struct spider_net_descr *descr, - struct spider_net_card *card, int napi) + struct spider_net_card *card) { struct sk_buff *skb; struct net_device *netdev; @@ -1001,20 +1046,22 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, netdev = card->netdev; - /* unmap descriptor */ - pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_FRAME, + /* check for errors in the data_error flag */ + if ((data_error & SPIDER_NET_DATA_ERROR_MASK) && + netif_msg_rx_err(card)) + pr_err("error in received descriptor found, " + "data_status=x%08x, data_error=x%08x\n", + data_status, data_error); + + /* prepare skb, unmap descriptor */ + skb = descr->skb; + pci_unmap_single(card->pdev, descr->buf_addr, SPIDER_NET_MAX_MTU, PCI_DMA_BIDIRECTIONAL); /* the cases we'll throw away the packet immediately */ - if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) { - if (netif_msg_rx_err(card)) - pr_err("error in received descriptor found, " - "data_status=x%08x, data_error=x%08x\n", - data_status, data_error); + if (data_error & SPIDER_NET_DESTROY_RX_FLAGS) return 0; - } - skb = descr->skb; skb->dev = netdev; skb_put(skb, descr->valid_size); @@ -1026,14 +1073,14 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, /* checksum offload */ if (card->options.rx_csum) { - if ( ( (data_status & SPIDER_NET_DATA_STATUS_CKSUM_MASK) == - SPIDER_NET_DATA_STATUS_CKSUM_MASK) && - !(data_error & SPIDER_NET_DATA_ERR_CKSUM_MASK)) + if ( (data_status & SPIDER_NET_DATA_STATUS_CHK_MASK) && + (!(data_error & SPIDER_NET_DATA_ERROR_CHK_MASK)) ) skb->ip_summed = CHECKSUM_UNNECESSARY; else skb->ip_summed = CHECKSUM_NONE; - } else + } else { skb->ip_summed = CHECKSUM_NONE; + } if (data_status & SPIDER_NET_VLAN_PACKET) { /* further enhancements: HW-accel VLAN @@ -1042,10 +1089,7 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, } /* pass skb up to stack */ - if (napi) - netif_receive_skb(skb); - else - netif_rx_ni(skb); + netif_receive_skb(skb); /* update netdevice statistics */ card->netdev_stats.rx_packets++; @@ -1055,18 +1099,16 @@ spider_net_pass_skb_up(struct spider_net_descr *descr, } /** - * spider_net_decode_one_descr - processes an rx descriptor + * spider_net_decode_descr - processes an rx descriptor * @card: card structure - * @napi: whether caller is in NAPI context * * returns 1 if a packet has been sent to the stack, otherwise 0 * * processes an rx descriptor by iommu-unmapping the data buffer and passing - * the packet up to the stack. This function is called in softirq - * context, e.g. either bottom half from interrupt or NAPI polling context + * the packet up to the stack */ static int -spider_net_decode_one_descr(struct spider_net_card *card, int napi) +spider_net_decode_one_descr(struct spider_net_card *card) { enum spider_net_descr_status status; struct spider_net_descr *descr; @@ -1080,19 +1122,17 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) if (status == SPIDER_NET_DESCR_CARDOWNED) { /* nothing in the descriptor yet */ - result=0; - goto out; + return 0; } if (status == SPIDER_NET_DESCR_NOT_IN_USE) { - /* not initialized yet, the ring must be empty */ + /* not initialized yet, I bet chain->tail == chain->head + * and the ring is empty */ spider_net_refill_rx_chain(card); - spider_net_enable_rxdmac(card); - result=0; - goto out; + return 0; } - /* descriptor definitively used -- move on tail */ + /* descriptor definitively used -- move on head */ chain->tail = descr->next; result = 0; @@ -1103,9 +1143,6 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) pr_err("%s: dropping RX descriptor with state %d\n", card->netdev->name, status); card->netdev_stats.rx_dropped++; - pci_unmap_single(card->pdev, descr->buf_addr, - SPIDER_NET_MAX_FRAME, PCI_DMA_BIDIRECTIONAL); - dev_kfree_skb_irq(descr->skb); goto refill; } @@ -1118,13 +1155,12 @@ spider_net_decode_one_descr(struct spider_net_card *card, int napi) } /* ok, we've got a packet in descr */ - result = spider_net_pass_skb_up(descr, card, napi); + result = spider_net_pass_skb_up(descr, card); refill: spider_net_set_descr_status(descr, SPIDER_NET_DESCR_NOT_IN_USE); /* change the descriptor state: */ - if (!napi) - spider_net_refill_rx_chain(card); -out: + spider_net_refill_rx_chain(card); + return result; } @@ -1150,7 +1186,7 @@ spider_net_poll(struct net_device *netdev, int *budget) packets_to_do = min(*budget, netdev->quota); while (packets_to_do) { - if (spider_net_decode_one_descr(card, 1)) { + if (spider_net_decode_one_descr(card)) { packets_done++; packets_to_do--; } else { @@ -1162,7 +1198,6 @@ spider_net_poll(struct net_device *netdev, int *budget) netdev->quota -= packets_done; *budget -= packets_done; - spider_net_refill_rx_chain(card); /* if all packets are in the stack, enable interrupts and return 0 */ /* if not, return 1 */ @@ -1306,24 +1341,6 @@ spider_net_enable_txdmac(struct spider_net_card *card) card->tx_chain.tail->bus_addr); } -/** - * spider_net_handle_rxram_full - cleans up RX ring upon RX RAM full interrupt - * @card: card structure - * - * spider_net_handle_rxram_full empties the RX ring so that spider can put - * more packets in it and empty its RX RAM. This is called in bottom half - * context - */ -static void -spider_net_handle_rxram_full(struct spider_net_card *card) -{ - while (spider_net_decode_one_descr(card, 0)) - ; - spider_net_enable_rxchtails(card); - spider_net_enable_rxdmac(card); - netif_rx_schedule(card->netdev); -} - /** * spider_net_handle_error_irq - handles errors raised by an interrupt * @card: card structure @@ -1432,21 +1449,17 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) switch (i) { case SPIDER_NET_GTMFLLINT: - if (netif_msg_intr(card) && net_ratelimit()) + if (netif_msg_intr(card)) pr_err("Spider TX RAM full\n"); show_error = 0; break; - case SPIDER_NET_GRFDFLLINT: /* fallthrough */ - case SPIDER_NET_GRFCFLLINT: /* fallthrough */ - case SPIDER_NET_GRFBFLLINT: /* fallthrough */ - case SPIDER_NET_GRFAFLLINT: /* fallthrough */ case SPIDER_NET_GRMFLLINT: - if (netif_msg_intr(card) && net_ratelimit()) + if (netif_msg_intr(card)) pr_err("Spider RX RAM full, incoming packets " - "might be discarded!\n"); - spider_net_rx_irq_off(card); - tasklet_schedule(&card->rxram_full_tl); - show_error = 0; + "might be discarded !\n"); + netif_rx_schedule(card->netdev); + spider_net_enable_rxchtails(card); + spider_net_enable_rxdmac(card); break; /* case SPIDER_NET_GTMSHTINT: problem, print a message */ @@ -1454,6 +1467,10 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) /* allrighty. tx from previous descr ok */ show_error = 0; break; + /* case SPIDER_NET_GRFDFLLINT: print a message down there */ + /* case SPIDER_NET_GRFCFLLINT: print a message down there */ + /* case SPIDER_NET_GRFBFLLINT: print a message down there */ + /* case SPIDER_NET_GRFAFLLINT: print a message down there */ /* chain end */ case SPIDER_NET_GDDDCEINT: /* fallthrough */ @@ -1465,7 +1482,6 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) "restarting DMAC %c.\n", 'D'+i-SPIDER_NET_GDDDCEINT); spider_net_refill_rx_chain(card); - spider_net_enable_rxdmac(card); show_error = 0; break; @@ -1476,7 +1492,6 @@ spider_net_handle_error_irq(struct spider_net_card *card, u32 status_reg) case SPIDER_NET_GDAINVDINT: /* could happen when rx chain is full */ spider_net_refill_rx_chain(card); - spider_net_enable_rxdmac(card); show_error = 0; break; @@ -1565,13 +1580,17 @@ spider_net_interrupt(int irq, void *ptr, struct pt_regs *regs) if (!status_reg) return IRQ_NONE; + if (status_reg & SPIDER_NET_TXINT) + spider_net_release_tx_chain(card, 0); + if (status_reg & SPIDER_NET_RXINT ) { spider_net_rx_irq_off(card); netif_rx_schedule(netdev); } - if (status_reg & SPIDER_NET_ERRINT ) - spider_net_handle_error_irq(card, status_reg); + /* we do this after rx and tx processing, as we want the tx chain + * processed to see, whether we should restart tx dma processing */ + spider_net_handle_error_irq(card, status_reg); /* clear interrupt sources */ spider_net_write_reg(card, SPIDER_NET_GHIINT0STS, status_reg); @@ -1812,40 +1831,34 @@ spider_net_setup_phy(struct spider_net_card *card) /** * spider_net_download_firmware - loads firmware into the adapter * @card: card structure - * @firmware_ptr: pointer to firmware data + * @firmware: firmware pointer * - * spider_net_download_firmware loads the firmware data into the - * adapter. It assumes the length etc. to be allright. + * spider_net_download_firmware loads the firmware opened by + * spider_net_init_firmware into the adapter. */ -static int +static void spider_net_download_firmware(struct spider_net_card *card, - u8 *firmware_ptr) + const struct firmware *firmware) { int sequencer, i; - u32 *fw_ptr = (u32 *)firmware_ptr; + u32 *fw_ptr = (u32 *)firmware->data; /* stop sequencers */ spider_net_write_reg(card, SPIDER_NET_GSINIT, SPIDER_NET_STOP_SEQ_VALUE); - for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; - sequencer++) { + for (sequencer = 0; sequencer < 6; sequencer++) { spider_net_write_reg(card, SPIDER_NET_GSnPRGADR + sequencer * 8, 0); - for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { + for (i = 0; i < SPIDER_NET_FIRMWARE_LEN; i++) { spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + sequencer * 8, *fw_ptr); fw_ptr++; } } - if (spider_net_read_reg(card, SPIDER_NET_GSINIT)) - return -EIO; - spider_net_write_reg(card, SPIDER_NET_GSINIT, SPIDER_NET_RUN_SEQ_VALUE); - - return 0; } /** @@ -1877,53 +1890,31 @@ spider_net_download_firmware(struct spider_net_card *card, static int spider_net_init_firmware(struct spider_net_card *card) { - struct firmware *firmware = NULL; - struct device_node *dn; - u8 *fw_prop = NULL; - int err = -ENOENT; - int fw_size; - - if (request_firmware((const struct firmware **)&firmware, - SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) == 0) { - if ( (firmware->size != SPIDER_NET_FIRMWARE_LEN) && - netif_msg_probe(card) ) { - pr_err("Incorrect size of spidernet firmware in " \ - "filesystem. Looking in host firmware...\n"); - goto try_host_fw; - } - err = spider_net_download_firmware(card, firmware->data); - - release_firmware(firmware); - if (err) - goto try_host_fw; + const struct firmware *firmware; + int err = -EIO; - goto done; + if (request_firmware(&firmware, + SPIDER_NET_FIRMWARE_NAME, &card->pdev->dev) < 0) { + if (netif_msg_probe(card)) + pr_err("Couldn't read in sequencer data file %s.\n", + SPIDER_NET_FIRMWARE_NAME); + firmware = NULL; + goto out; } -try_host_fw: - dn = pci_device_to_OF_node(card->pdev); - if (!dn) - goto out_err; - - fw_prop = (u8 *)get_property(dn, "firmware", &fw_size); - if (!fw_prop) - goto out_err; - - if ( (fw_size != SPIDER_NET_FIRMWARE_LEN) && - netif_msg_probe(card) ) { - pr_err("Incorrect size of spidernet firmware in " \ - "host firmware\n"); - goto done; + if (firmware->size != 6 * SPIDER_NET_FIRMWARE_LEN * sizeof(u32)) { + if (netif_msg_probe(card)) + pr_err("Invalid size of sequencer data file %s.\n", + SPIDER_NET_FIRMWARE_NAME); + goto out; } - err = spider_net_download_firmware(card, fw_prop); + spider_net_download_firmware(card, firmware); + + err = 0; +out: + release_firmware(firmware); -done: - return err; -out_err: - if (netif_msg_probe(card)) - pr_err("Couldn't find spidernet firmware in filesystem " \ - "or host firmware\n"); return err; } @@ -1943,11 +1934,10 @@ spider_net_workaround_rxramfull(struct spider_net_card *card) SPIDER_NET_CKRCTRL_RUN_VALUE); /* empty sequencer data */ - for (sequencer = 0; sequencer < SPIDER_NET_FIRMWARE_SEQS; - sequencer++) { + for (sequencer = 0; sequencer < 6; sequencer++) { spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + sequencer * 8, 0x0); - for (i = 0; i < SPIDER_NET_FIRMWARE_SEQWORDS; i++) { + for (i = 0; i < SPIDER_NET_FIRMWARE_LEN; i++) { spider_net_write_reg(card, SPIDER_NET_GSnPRGDAT + sequencer * 8, 0x0); } @@ -2071,15 +2061,7 @@ spider_net_setup_netdev(struct spider_net_card *card) SET_NETDEV_DEV(netdev, &card->pdev->dev); pci_set_drvdata(card->pdev, netdev); - - atomic_set(&card->tx_chain_release,0); - card->rxram_full_tl.data = (unsigned long) card; - card->rxram_full_tl.func = - (void (*)(unsigned long)) spider_net_handle_rxram_full; - init_timer(&card->tx_timer); - card->tx_timer.function = - (void (*)(unsigned long)) spider_net_cleanup_tx_ring; - card->tx_timer.data = (unsigned long) card; + spin_lock_init(&card->intmask_lock); netdev->irq = card->pdev->irq; card->options.rx_csum = SPIDER_NET_RX_CSUM_DEFAULT; diff --git a/trunk/drivers/net/spider_net.h b/trunk/drivers/net/spider_net.h index 5922b529a048..22b2f2347351 100644 --- a/trunk/drivers/net/spider_net.h +++ b/trunk/drivers/net/spider_net.h @@ -33,32 +33,25 @@ extern struct ethtool_ops spider_net_ethtool_ops; extern char spider_net_driver_name[]; -#define SPIDER_NET_MAX_FRAME 2312 -#define SPIDER_NET_MAX_MTU 2294 +#define SPIDER_NET_MAX_MTU 2308 #define SPIDER_NET_MIN_MTU 64 #define SPIDER_NET_RXBUF_ALIGN 128 -#define SPIDER_NET_RX_DESCRIPTORS_DEFAULT 256 +#define SPIDER_NET_RX_DESCRIPTORS_DEFAULT 64 #define SPIDER_NET_RX_DESCRIPTORS_MIN 16 -#define SPIDER_NET_RX_DESCRIPTORS_MAX 512 +#define SPIDER_NET_RX_DESCRIPTORS_MAX 256 -#define SPIDER_NET_TX_DESCRIPTORS_DEFAULT 256 +#define SPIDER_NET_TX_DESCRIPTORS_DEFAULT 64 #define SPIDER_NET_TX_DESCRIPTORS_MIN 16 -#define SPIDER_NET_TX_DESCRIPTORS_MAX 512 - -#define SPIDER_NET_TX_TIMER 20 +#define SPIDER_NET_TX_DESCRIPTORS_MAX 256 #define SPIDER_NET_RX_CSUM_DEFAULT 1 -#define SPIDER_NET_WATCHDOG_TIMEOUT 50*HZ -#define SPIDER_NET_NAPI_WEIGHT 64 +#define SPIDER_NET_WATCHDOG_TIMEOUT 5*HZ +#define SPIDER_NET_NAPI_WEIGHT 64 -#define SPIDER_NET_FIRMWARE_SEQS 6 -#define SPIDER_NET_FIRMWARE_SEQWORDS 1024 -#define SPIDER_NET_FIRMWARE_LEN (SPIDER_NET_FIRMWARE_SEQS * \ - SPIDER_NET_FIRMWARE_SEQWORDS * \ - sizeof(u32)) +#define SPIDER_NET_FIRMWARE_LEN 1024 #define SPIDER_NET_FIRMWARE_NAME "spider_fw.bin" /** spider_net SMMIO registers */ @@ -149,12 +142,14 @@ extern char spider_net_driver_name[]; /** SCONFIG registers */ #define SPIDER_NET_SCONFIG_IOACTE 0x00002810 -/** interrupt mask registers */ -#define SPIDER_NET_INT0_MASK_VALUE 0x3f7fe2c7 -#define SPIDER_NET_INT1_MASK_VALUE 0xffff7ff7 +/** hardcoded register values */ +#define SPIDER_NET_INT0_MASK_VALUE 0x3f7fe3ff +#define SPIDER_NET_INT1_MASK_VALUE 0xffffffff /* no MAC aborts -> auto retransmission */ -#define SPIDER_NET_INT2_MASK_VALUE 0xffef7ff1 +#define SPIDER_NET_INT2_MASK_VALUE 0xfffffff1 +/* clear counter when interrupt sources are cleared +#define SPIDER_NET_FRAMENUM_VALUE 0x0001f001 */ /* we rely on flagged descriptor interrupts */ #define SPIDER_NET_FRAMENUM_VALUE 0x00000000 /* set this first, then the FRAMENUM_VALUE */ @@ -173,7 +168,7 @@ extern char spider_net_driver_name[]; #if 0 #define SPIDER_NET_WOL_VALUE 0x00000000 #endif -#define SPIDER_NET_IPSECINIT_VALUE 0x6f716f71 +#define SPIDER_NET_IPSECINIT_VALUE 0x00f000f8 /* pause frames: automatic, no upper retransmission count */ /* outside loopback mode: ETOMOD signal dont matter, not connected */ @@ -323,10 +318,6 @@ enum spider_net_int2_status { #define SPIDER_NET_RXINT ( (1 << SPIDER_NET_GDAFDCINT) | \ (1 << SPIDER_NET_GRMFLLINT) ) -#define SPIDER_NET_ERRINT ( 0xffffffff & \ - (~SPIDER_NET_TXINT) & \ - (~SPIDER_NET_RXINT) ) - #define SPIDER_NET_GPREXEC 0x80000000 #define SPIDER_NET_GPRDAT_MASK 0x0000ffff @@ -367,6 +358,9 @@ enum spider_net_int2_status { /* descr ready, descr is in middle of chain, get interrupt on completion */ #define SPIDER_NET_DMAC_RX_CARDOWNED 0xa0800000 +/* multicast is no problem */ +#define SPIDER_NET_DATA_ERROR_MASK 0xffffbfff + enum spider_net_descr_status { SPIDER_NET_DESCR_COMPLETE = 0x00, /* used in rx and tx */ SPIDER_NET_DESCR_RESPONSE_ERROR = 0x01, /* used in rx and tx */ @@ -379,9 +373,9 @@ enum spider_net_descr_status { struct spider_net_descr { /* as defined by the hardware */ - u32 buf_addr; + dma_addr_t buf_addr; u32 buf_size; - u32 next_descr_addr; + dma_addr_t next_descr_addr; u32 dmac_cmd_status; u32 result_size; u32 valid_size; /* all zeroes for tx */ @@ -390,7 +384,7 @@ struct spider_net_descr { /* used in the driver */ struct sk_buff *skb; - u32 bus_addr; + dma_addr_t bus_addr; struct spider_net_descr *next; struct spider_net_descr *prev; } __attribute__((aligned(32))); @@ -402,21 +396,21 @@ struct spider_net_descr_chain { }; /* descriptor data_status bits */ -#define SPIDER_NET_RX_IPCHK 29 -#define SPIDER_NET_RX_TCPCHK 28 +#define SPIDER_NET_RXIPCHK 29 +#define SPIDER_NET_TCPUDPIPCHK 28 +#define SPIDER_NET_DATA_STATUS_CHK_MASK (1 << SPIDER_NET_RXIPCHK | \ + 1 << SPIDER_NET_TCPUDPIPCHK) + #define SPIDER_NET_VLAN_PACKET 21 -#define SPIDER_NET_DATA_STATUS_CKSUM_MASK ( (1 << SPIDER_NET_RX_IPCHK) | \ - (1 << SPIDER_NET_RX_TCPCHK) ) /* descriptor data_error bits */ -#define SPIDER_NET_RX_IPCHKERR 27 -#define SPIDER_NET_RX_RXTCPCHKERR 28 - -#define SPIDER_NET_DATA_ERR_CKSUM_MASK (1 << SPIDER_NET_RX_IPCHKERR) +#define SPIDER_NET_RXIPCHKERR 27 +#define SPIDER_NET_RXTCPCHKERR 26 +#define SPIDER_NET_DATA_ERROR_CHK_MASK (1 << SPIDER_NET_RXIPCHKERR | \ + 1 << SPIDER_NET_RXTCPCHKERR) -/* the cases we don't pass the packet to the stack. - * 701b8000 would be correct, but every packets gets that flag */ -#define SPIDER_NET_DESTROY_RX_FLAGS 0x700b8000 +/* the cases we don't pass the packet to the stack */ +#define SPIDER_NET_DESTROY_RX_FLAGS 0x70138000 #define SPIDER_NET_DESCR_SIZE 32 @@ -451,16 +445,13 @@ struct spider_net_card { struct spider_net_descr_chain tx_chain; struct spider_net_descr_chain rx_chain; - atomic_t rx_chain_refill; - atomic_t tx_chain_release; + spinlock_t chain_lock; struct net_device_stats netdev_stats; struct spider_net_options options; spinlock_t intmask_lock; - struct tasklet_struct rxram_full_tl; - struct timer_list tx_timer; struct work_struct tx_timeout_task; atomic_t tx_timeout_task_counter; diff --git a/trunk/drivers/net/spider_net_ethtool.c b/trunk/drivers/net/spider_net_ethtool.c index a5bb0b7633af..d42e60ba74ce 100644 --- a/trunk/drivers/net/spider_net_ethtool.c +++ b/trunk/drivers/net/spider_net_ethtool.c @@ -113,23 +113,6 @@ spider_net_ethtool_set_rx_csum(struct net_device *netdev, u32 n) return 0; } -static uint32_t -spider_net_ethtool_get_tx_csum(struct net_device *netdev) -{ - return (netdev->features & NETIF_F_HW_CSUM) != 0; -} - -static int -spider_net_ethtool_set_tx_csum(struct net_device *netdev, uint32_t data) -{ - if (data) - netdev->features |= NETIF_F_HW_CSUM; - else - netdev->features &= ~NETIF_F_HW_CSUM; - - return 0; -} - struct ethtool_ops spider_net_ethtool_ops = { .get_settings = spider_net_ethtool_get_settings, .get_drvinfo = spider_net_ethtool_get_drvinfo, @@ -139,7 +122,5 @@ struct ethtool_ops spider_net_ethtool_ops = { .nway_reset = spider_net_ethtool_nway_reset, .get_rx_csum = spider_net_ethtool_get_rx_csum, .set_rx_csum = spider_net_ethtool_set_rx_csum, - .get_tx_csum = spider_net_ethtool_get_tx_csum, - .set_tx_csum = spider_net_ethtool_set_tx_csum, }; diff --git a/trunk/drivers/net/starfire.c b/trunk/drivers/net/starfire.c index ed5458c45446..d167deda9a53 100644 --- a/trunk/drivers/net/starfire.c +++ b/trunk/drivers/net/starfire.c @@ -2084,38 +2084,6 @@ static int netdev_close(struct net_device *dev) return 0; } -#ifdef CONFIG_PM -static int starfire_suspend(struct pci_dev *pdev, pm_message_t state) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - if (netif_running(dev)) { - netif_device_detach(dev); - netdev_close(dev); - } - - pci_save_state(pdev); - pci_set_power_state(pdev, pci_choose_state(pdev,state)); - - return 0; -} - -static int starfire_resume(struct pci_dev *pdev) -{ - struct net_device *dev = pci_get_drvdata(pdev); - - pci_set_power_state(pdev, PCI_D0); - pci_restore_state(pdev); - - if (netif_running(dev)) { - netdev_open(dev); - netif_device_attach(dev); - } - - return 0; -} -#endif /* CONFIG_PM */ - static void __devexit starfire_remove_one (struct pci_dev *pdev) { @@ -2147,10 +2115,6 @@ static struct pci_driver starfire_driver = { .name = DRV_NAME, .probe = starfire_init_one, .remove = __devexit_p(starfire_remove_one), -#ifdef CONFIG_PM - .suspend = starfire_suspend, - .resume = starfire_resume, -#endif /* CONFIG_PM */ .id_table = starfire_pci_tbl, }; diff --git a/trunk/drivers/net/wireless/airo.c b/trunk/drivers/net/wireless/airo.c index a4c7ae94614d..ee866fd6957d 100644 --- a/trunk/drivers/net/wireless/airo.c +++ b/trunk/drivers/net/wireless/airo.c @@ -5668,13 +5668,13 @@ static int airo_set_freq(struct net_device *dev, int channel = fwrq->m; /* We should do a better check than that, * based on the card capability !!! */ - if((channel < 1) || (channel > 14)) { + if((channel < 1) || (channel > 16)) { printk(KERN_DEBUG "%s: New channel value of %d is invalid!\n", dev->name, fwrq->m); rc = -EINVAL; } else { readConfigRid(local, 1); /* Yes ! We can set it !!! */ - local->config.channelSet = (u16) channel; + local->config.channelSet = (u16)(channel - 1); set_bit (FLAG_COMMIT, &local->flags); } } @@ -5692,7 +5692,6 @@ static int airo_get_freq(struct net_device *dev, { struct airo_info *local = dev->priv; StatusRid status_rid; /* Card status info */ - int ch; readConfigRid(local, 1); if ((local->config.opmode & 0xFF) == MODE_STA_ESS) @@ -5700,14 +5699,16 @@ static int airo_get_freq(struct net_device *dev, else readStatusRid(local, &status_rid, 1); - ch = (int)status_rid.channel; - if((ch > 0) && (ch < 15)) { - fwrq->m = frequency_list[ch - 1] * 100000; +#ifdef WEXT_USECHANNELS + fwrq->m = ((int)status_rid.channel) + 1; + fwrq->e = 0; +#else + { + int f = (int)status_rid.channel; + fwrq->m = frequency_list[f] * 100000; fwrq->e = 1; - } else { - fwrq->m = ch; - fwrq->e = 0; } +#endif return 0; } @@ -5782,7 +5783,7 @@ static int airo_get_essid(struct net_device *dev, /* If none, we may want to get the one that was set */ /* Push it out ! */ - dwrq->length = status_rid.SSIDlen; + dwrq->length = status_rid.SSIDlen + 1; dwrq->flags = 1; /* active */ return 0; diff --git a/trunk/drivers/net/wireless/atmel.c b/trunk/drivers/net/wireless/atmel.c index 98a76f10a0f7..f0ccfef66445 100644 --- a/trunk/drivers/net/wireless/atmel.c +++ b/trunk/drivers/net/wireless/atmel.c @@ -1718,11 +1718,11 @@ static int atmel_get_essid(struct net_device *dev, if (priv->new_SSID_size != 0) { memcpy(extra, priv->new_SSID, priv->new_SSID_size); extra[priv->new_SSID_size] = '\0'; - dwrq->length = priv->new_SSID_size; + dwrq->length = priv->new_SSID_size + 1; } else { memcpy(extra, priv->SSID, priv->SSID_size); extra[priv->SSID_size] = '\0'; - dwrq->length = priv->SSID_size; + dwrq->length = priv->SSID_size + 1; } dwrq->flags = !priv->connect_to_any_BSS; /* active */ diff --git a/trunk/drivers/net/wireless/hostap/Kconfig b/trunk/drivers/net/wireless/hostap/Kconfig index c8f6286dd35f..56f41c714d38 100644 --- a/trunk/drivers/net/wireless/hostap/Kconfig +++ b/trunk/drivers/net/wireless/hostap/Kconfig @@ -26,25 +26,11 @@ config HOSTAP_FIRMWARE depends on HOSTAP ---help--- Configure Host AP driver to include support for firmware image - download. This option by itself only enables downloading to the - volatile memory, i.e. the card RAM. This option is required to - support cards that don't have firmware in flash, such as D-Link - DWL-520 rev E and D-Link DWL-650 rev P. + download. Current version supports only downloading to volatile, i.e., + RAM memory. Flash upgrade is not yet supported. - Firmware image downloading needs a user space tool, prism2_srec. - It is available from http://hostap.epitest.fi/. - -config HOSTAP_FIRMWARE_NVRAM - bool "Support for non-volatile firmware download" - depends on HOSTAP_FIRMWARE - ---help--- - Allow Host AP driver to write firmware images to the non-volatile - card memory, i.e. flash memory that survives power cycling. - Enable this option if you want to be able to change card firmware - permanently. - - Firmware image downloading needs a user space tool, prism2_srec. - It is available from http://hostap.epitest.fi/. + Firmware image downloading needs user space tool, prism2_srec. It is + available from http://hostap.epitest.fi/. config HOSTAP_PLX tristate "Host AP driver for Prism2/2.5/3 in PLX9052 PCI adaptors" diff --git a/trunk/drivers/net/wireless/hostap/Makefile b/trunk/drivers/net/wireless/hostap/Makefile index b8e41a702c00..353ccb93134b 100644 --- a/trunk/drivers/net/wireless/hostap/Makefile +++ b/trunk/drivers/net/wireless/hostap/Makefile @@ -1,5 +1,4 @@ -hostap-y := hostap_80211_rx.o hostap_80211_tx.o hostap_ap.o hostap_info.o \ - hostap_ioctl.o hostap_main.o hostap_proc.o +hostap-y := hostap_main.o obj-$(CONFIG_HOSTAP) += hostap.o obj-$(CONFIG_HOSTAP_CS) += hostap_cs.o diff --git a/trunk/drivers/net/wireless/hostap/hostap.h b/trunk/drivers/net/wireless/hostap/hostap.h index 5e63765219fe..5fac89b8ce3a 100644 --- a/trunk/drivers/net/wireless/hostap/hostap.h +++ b/trunk/drivers/net/wireless/hostap/hostap.h @@ -1,15 +1,6 @@ #ifndef HOSTAP_H #define HOSTAP_H -#include - -#include "hostap_wlan.h" -#include "hostap_ap.h" - -static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, - 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; -#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0])) - /* hostap.c */ extern struct proc_dir_entry *hostap_proc; @@ -49,26 +40,6 @@ int prism2_update_comms_qual(struct net_device *dev); int prism2_sta_send_mgmt(local_info_t *local, u8 *dst, u16 stype, u8 *body, size_t bodylen); int prism2_sta_deauth(local_info_t *local, u16 reason); -int prism2_wds_add(local_info_t *local, u8 *remote_addr, - int rtnl_locked); -int prism2_wds_del(local_info_t *local, u8 *remote_addr, - int rtnl_locked, int do_not_remove); - - -/* hostap_ap.c */ - -int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac); -int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac); -void ap_control_flush_macs(struct mac_restrictions *mac_restrictions); -int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac); -void ap_control_kickall(struct ap_data *ap); -void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, - struct ieee80211_crypt_data ***crypt); -int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], - struct iw_quality qual[], int buf_size, - int aplist); -int prism2_ap_translate_scan(struct net_device *dev, char *buffer); -int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param); /* hostap_proc.c */ @@ -83,12 +54,4 @@ void hostap_info_init(local_info_t *local); void hostap_info_process(local_info_t *local, struct sk_buff *skb); -/* hostap_ioctl.c */ - -extern const struct iw_handler_def hostap_iw_handler_def; -extern struct ethtool_ops prism2_ethtool_ops; - -int hostap_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd); - - #endif /* HOSTAP_H */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211.h b/trunk/drivers/net/wireless/hostap/hostap_80211.h index 1fc72fe511e9..bf506f50d722 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_80211.h +++ b/trunk/drivers/net/wireless/hostap/hostap_80211.h @@ -1,9 +1,6 @@ #ifndef HOSTAP_80211_H #define HOSTAP_80211_H -#include -#include - struct hostap_ieee80211_mgmt { u16 frame_control; u16 duration; diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c b/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c index 7e04dc94b3bc..4b13b76425c1 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c +++ b/trunk/drivers/net/wireless/hostap/hostap_80211_rx.c @@ -1,18 +1,7 @@ #include -#include #include "hostap_80211.h" #include "hostap.h" -#include "hostap_ap.h" - -/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ -/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -static unsigned char rfc1042_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; -/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -static unsigned char bridge_tunnel_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; -/* No encapsulation header if EtherType < 0x600 (=length) */ void hostap_dump_rx_80211(const char *name, struct sk_buff *skb, struct hostap_80211_rx_status *rx_stats) diff --git a/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c b/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c index 4a85e63906f1..9d24f8a38ac5 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c +++ b/trunk/drivers/net/wireless/hostap/hostap_80211_tx.c @@ -1,18 +1,3 @@ -#include "hostap_80211.h" -#include "hostap_common.h" -#include "hostap_wlan.h" -#include "hostap.h" -#include "hostap_ap.h" - -/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ -/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ -static unsigned char rfc1042_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; -/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ -static unsigned char bridge_tunnel_header[] = -{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; -/* No encapsulation header if EtherType < 0x600 (=length) */ - void hostap_dump_tx_80211(const char *name, struct sk_buff *skb) { struct ieee80211_hdr_4addr *hdr; diff --git a/trunk/drivers/net/wireless/hostap/hostap_ap.c b/trunk/drivers/net/wireless/hostap/hostap_ap.c index 753a1de6664b..9da94ab7f05f 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_ap.c +++ b/trunk/drivers/net/wireless/hostap/hostap_ap.c @@ -16,14 +16,6 @@ * (8802.11: 5.5) */ -#include -#include -#include - -#include "hostap_wlan.h" -#include "hostap.h" -#include "hostap_ap.h" - static int other_ap_policy[MAX_PARM_DEVICES] = { AP_OTHER_AP_SKIP_ALL, DEF_INTS }; module_param_array(other_ap_policy, int, NULL, 0444); @@ -368,7 +360,8 @@ static int ap_control_proc_read(char *page, char **start, off_t off, } -int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac) +static int ap_control_add_mac(struct mac_restrictions *mac_restrictions, + u8 *mac) { struct mac_entry *entry; @@ -387,7 +380,8 @@ int ap_control_add_mac(struct mac_restrictions *mac_restrictions, u8 *mac) } -int ap_control_del_mac(struct mac_restrictions *mac_restrictions, u8 *mac) +static int ap_control_del_mac(struct mac_restrictions *mac_restrictions, + u8 *mac) { struct list_head *ptr; struct mac_entry *entry; @@ -439,7 +433,7 @@ static int ap_control_mac_deny(struct mac_restrictions *mac_restrictions, } -void ap_control_flush_macs(struct mac_restrictions *mac_restrictions) +static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions) { struct list_head *ptr, *n; struct mac_entry *entry; @@ -460,7 +454,8 @@ void ap_control_flush_macs(struct mac_restrictions *mac_restrictions) } -int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac) +static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, + u8 *mac) { struct sta_info *sta; u16 resp; @@ -491,7 +486,7 @@ int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, u8 *mac) #endif /* PRISM2_NO_KERNEL_IEEE80211_MGMT */ -void ap_control_kickall(struct ap_data *ap) +static void ap_control_kickall(struct ap_data *ap) { struct list_head *ptr, *n; struct sta_info *sta; @@ -2326,9 +2321,9 @@ static void schedule_packet_send(local_info_t *local, struct sta_info *sta) } -int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], - struct iw_quality qual[], int buf_size, - int aplist) +static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], + struct iw_quality qual[], int buf_size, + int aplist) { struct ap_data *ap = local->ap; struct list_head *ptr; @@ -2368,7 +2363,7 @@ int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], /* Translate our list of Access Points & Stations to a card independant * format that the Wireless Tools will understand - Jean II */ -int prism2_ap_translate_scan(struct net_device *dev, char *buffer) +static int prism2_ap_translate_scan(struct net_device *dev, char *buffer) { struct hostap_interface *iface; local_info_t *local; @@ -2613,7 +2608,8 @@ static int prism2_hostapd_sta_clear_stats(struct ap_data *ap, } -int prism2_hostapd(struct ap_data *ap, struct prism2_hostapd_param *param) +static int prism2_hostapd(struct ap_data *ap, + struct prism2_hostapd_param *param) { switch (param->cmd) { case PRISM2_HOSTAPD_FLUSH: @@ -3211,8 +3207,8 @@ void hostap_update_rates(local_info_t *local) } -void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, - struct ieee80211_crypt_data ***crypt) +static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, + struct ieee80211_crypt_data ***crypt) { struct sta_info *sta; diff --git a/trunk/drivers/net/wireless/hostap/hostap_ap.h b/trunk/drivers/net/wireless/hostap/hostap_ap.h index 2fa2452b6b07..6d00df69c2e3 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_ap.h +++ b/trunk/drivers/net/wireless/hostap/hostap_ap.h @@ -1,8 +1,6 @@ #ifndef HOSTAP_AP_H #define HOSTAP_AP_H -#include "hostap_80211.h" - /* AP data structures for STAs */ /* maximum number of frames to buffer per STA */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_common.h b/trunk/drivers/net/wireless/hostap/hostap_common.h index 01624005d808..6f4fa9dc308f 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_common.h +++ b/trunk/drivers/net/wireless/hostap/hostap_common.h @@ -1,9 +1,6 @@ #ifndef HOSTAP_COMMON_H #define HOSTAP_COMMON_H -#include -#include - #define BIT(x) (1 << (x)) #define MAC2STR(a) (a)[0], (a)[1], (a)[2], (a)[3], (a)[4], (a)[5] diff --git a/trunk/drivers/net/wireless/hostap/hostap_config.h b/trunk/drivers/net/wireless/hostap/hostap_config.h index c090a5aebb58..7ed3425d08c1 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_config.h +++ b/trunk/drivers/net/wireless/hostap/hostap_config.h @@ -21,10 +21,15 @@ #define PRISM2_DOWNLOAD_SUPPORT #endif -/* Allow kernel configuration to enable non-volatile download support. */ -#ifdef CONFIG_HOSTAP_FIRMWARE_NVRAM -#define PRISM2_NON_VOLATILE_DOWNLOAD -#endif +#ifdef PRISM2_DOWNLOAD_SUPPORT +/* Allow writing firmware images into flash, i.e., to non-volatile storage. + * Before you enable this option, you should make absolutely sure that you are + * using prism2_srec utility that comes with THIS version of the driver! + * In addition, please note that it is possible to kill your card with + * non-volatile download if you are using incorrect image. This feature has not + * been fully tested, so please be careful with it. */ +/* #define PRISM2_NON_VOLATILE_DOWNLOAD */ +#endif /* PRISM2_DOWNLOAD_SUPPORT */ /* Save low-level I/O for debugging. This should not be enabled in normal use. */ diff --git a/trunk/drivers/net/wireless/hostap/hostap_info.c b/trunk/drivers/net/wireless/hostap/hostap_info.c index 50f72d831cf4..5aa998fdf1c4 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_info.c +++ b/trunk/drivers/net/wireless/hostap/hostap_info.c @@ -1,8 +1,5 @@ /* Host AP driver Info Frame processing (part of hostap.o module) */ -#include "hostap_wlan.h" -#include "hostap.h" -#include "hostap_ap.h" /* Called only as a tasklet (software IRQ) */ static void prism2_info_commtallies16(local_info_t *local, unsigned char *buf, diff --git a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c b/trunk/drivers/net/wireless/hostap/hostap_ioctl.c index f3e0ce1ee037..2617d70bcda9 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_ioctl.c +++ b/trunk/drivers/net/wireless/hostap/hostap_ioctl.c @@ -1,13 +1,11 @@ /* ioctl() (mostly Linux Wireless Extensions) routines for Host AP driver */ -#include +#ifdef in_atomic +/* Get kernel_locked() for in_atomic() */ #include +#endif #include -#include -#include "hostap_wlan.h" -#include "hostap.h" -#include "hostap_ap.h" static struct iw_statistics *hostap_get_wireless_stats(struct net_device *dev) { @@ -3912,7 +3910,7 @@ static void prism2_get_drvinfo(struct net_device *dev, local->sta_fw_ver & 0xff); } -struct ethtool_ops prism2_ethtool_ops = { +static struct ethtool_ops prism2_ethtool_ops = { .get_drvinfo = prism2_get_drvinfo }; @@ -3987,7 +3985,7 @@ static const iw_handler prism2_private_handler[] = (iw_handler) prism2_ioctl_priv_readmif, /* 3 */ }; -const struct iw_handler_def hostap_iw_handler_def = +static const struct iw_handler_def hostap_iw_handler_def = { .num_standard = sizeof(prism2_handler) / sizeof(iw_handler), .num_private = sizeof(prism2_private_handler) / sizeof(iw_handler), diff --git a/trunk/drivers/net/wireless/hostap/hostap_main.c b/trunk/drivers/net/wireless/hostap/hostap_main.c index 8dd4c4446a64..3d2ea61033be 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_main.c +++ b/trunk/drivers/net/wireless/hostap/hostap_main.c @@ -24,7 +24,6 @@ #include #include #include -#include #include #include #include @@ -48,6 +47,57 @@ MODULE_VERSION(PRISM2_VERSION); #define PRISM2_MAX_MTU (PRISM2_MAX_FRAME_SIZE - (6 /* LLC */ + 8 /* WEP */)) +/* hostap.c */ +static int prism2_wds_add(local_info_t *local, u8 *remote_addr, + int rtnl_locked); +static int prism2_wds_del(local_info_t *local, u8 *remote_addr, + int rtnl_locked, int do_not_remove); + +/* hostap_ap.c */ +static int prism2_ap_get_sta_qual(local_info_t *local, struct sockaddr addr[], + struct iw_quality qual[], int buf_size, + int aplist); +static int prism2_ap_translate_scan(struct net_device *dev, char *buffer); +static int prism2_hostapd(struct ap_data *ap, + struct prism2_hostapd_param *param); +static void * ap_crypt_get_ptrs(struct ap_data *ap, u8 *addr, int permanent, + struct ieee80211_crypt_data ***crypt); +static void ap_control_kickall(struct ap_data *ap); +#ifndef PRISM2_NO_KERNEL_IEEE80211_MGMT +static int ap_control_add_mac(struct mac_restrictions *mac_restrictions, + u8 *mac); +static int ap_control_del_mac(struct mac_restrictions *mac_restrictions, + u8 *mac); +static void ap_control_flush_macs(struct mac_restrictions *mac_restrictions); +static int ap_control_kick_mac(struct ap_data *ap, struct net_device *dev, + u8 *mac); +#endif /* !PRISM2_NO_KERNEL_IEEE80211_MGMT */ + + +static const long freq_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442, + 2447, 2452, 2457, 2462, 2467, 2472, 2484 }; +#define FREQ_COUNT (sizeof(freq_list) / sizeof(freq_list[0])) + + +/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */ +/* Ethernet-II snap header (RFC1042 for most EtherTypes) */ +static unsigned char rfc1042_header[] = +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 }; +/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ +static unsigned char bridge_tunnel_header[] = +{ 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 }; +/* No encapsulation header if EtherType < 0x600 (=length) */ + + +/* FIX: these could be compiled separately and linked together to hostap.o */ +#include "hostap_ap.c" +#include "hostap_info.c" +#include "hostap_ioctl.c" +#include "hostap_proc.c" +#include "hostap_80211_rx.c" +#include "hostap_80211_tx.c" + + struct net_device * hostap_add_interface(struct local_info *local, int type, int rtnl_locked, const char *prefix, @@ -146,8 +196,8 @@ static inline int prism2_wds_special_addr(u8 *addr) } -int prism2_wds_add(local_info_t *local, u8 *remote_addr, - int rtnl_locked) +static int prism2_wds_add(local_info_t *local, u8 *remote_addr, + int rtnl_locked) { struct net_device *dev; struct list_head *ptr; @@ -208,8 +258,8 @@ int prism2_wds_add(local_info_t *local, u8 *remote_addr, } -int prism2_wds_del(local_info_t *local, u8 *remote_addr, - int rtnl_locked, int do_not_remove) +static int prism2_wds_del(local_info_t *local, u8 *remote_addr, + int rtnl_locked, int do_not_remove) { unsigned long flags; struct list_head *ptr; diff --git a/trunk/drivers/net/wireless/hostap/hostap_proc.c b/trunk/drivers/net/wireless/hostap/hostap_proc.c index d1d8ce022e63..a0a4cbd4937a 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_proc.c +++ b/trunk/drivers/net/wireless/hostap/hostap_proc.c @@ -1,12 +1,5 @@ /* /proc routines for Host AP driver */ -#include -#include -#include - -#include "hostap_wlan.h" -#include "hostap.h" - #define PROC_LIMIT (PAGE_SIZE - 80) diff --git a/trunk/drivers/net/wireless/hostap/hostap_wlan.h b/trunk/drivers/net/wireless/hostap/hostap_wlan.h index 87a54aa6f4dd..cfd801559492 100644 --- a/trunk/drivers/net/wireless/hostap/hostap_wlan.h +++ b/trunk/drivers/net/wireless/hostap/hostap_wlan.h @@ -1,10 +1,6 @@ #ifndef HOSTAP_WLAN_H #define HOSTAP_WLAN_H -#include -#include -#include - #include "hostap_config.h" #include "hostap_common.h" diff --git a/trunk/drivers/net/wireless/ipw2100.c b/trunk/drivers/net/wireless/ipw2100.c index 8bf02763b5c7..7518384f34d9 100644 --- a/trunk/drivers/net/wireless/ipw2100.c +++ b/trunk/drivers/net/wireless/ipw2100.c @@ -5735,6 +5735,70 @@ static struct net_device_stats *ipw2100_stats(struct net_device *dev) return &priv->ieee->stats; } +#if WIRELESS_EXT < 18 +/* Support for wpa_supplicant before WE-18, deprecated. */ + +/* following definitions must match definitions in driver_ipw.c */ + +#define IPW2100_IOCTL_WPA_SUPPLICANT SIOCIWFIRSTPRIV+30 + +#define IPW2100_CMD_SET_WPA_PARAM 1 +#define IPW2100_CMD_SET_WPA_IE 2 +#define IPW2100_CMD_SET_ENCRYPTION 3 +#define IPW2100_CMD_MLME 4 + +#define IPW2100_PARAM_WPA_ENABLED 1 +#define IPW2100_PARAM_TKIP_COUNTERMEASURES 2 +#define IPW2100_PARAM_DROP_UNENCRYPTED 3 +#define IPW2100_PARAM_PRIVACY_INVOKED 4 +#define IPW2100_PARAM_AUTH_ALGS 5 +#define IPW2100_PARAM_IEEE_802_1X 6 + +#define IPW2100_MLME_STA_DEAUTH 1 +#define IPW2100_MLME_STA_DISASSOC 2 + +#define IPW2100_CRYPT_ERR_UNKNOWN_ALG 2 +#define IPW2100_CRYPT_ERR_UNKNOWN_ADDR 3 +#define IPW2100_CRYPT_ERR_CRYPT_INIT_FAILED 4 +#define IPW2100_CRYPT_ERR_KEY_SET_FAILED 5 +#define IPW2100_CRYPT_ERR_TX_KEY_SET_FAILED 6 +#define IPW2100_CRYPT_ERR_CARD_CONF_FAILED 7 + +#define IPW2100_CRYPT_ALG_NAME_LEN 16 + +struct ipw2100_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[IPW2100_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 /* WIRELESS_EXT < 18 */ + static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value) { /* This is called when wpa_supplicant loads and closes the driver @@ -5743,6 +5807,11 @@ static int ipw2100_wpa_enable(struct ipw2100_priv *priv, int value) return 0; } +#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) { @@ -5786,6 +5855,360 @@ void ipw2100_wpa_assoc_frame(struct ipw2100_priv *priv, 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) { + case IPW2100_PARAM_WPA_ENABLED: + ret = ipw2100_wpa_enable(priv, value); + break; + + case IPW2100_PARAM_TKIP_COUNTERMEASURES: + crypt = priv->ieee->crypt[priv->ieee->tx_keyidx]; + if (!crypt || !crypt->ops->set_flags || !crypt->ops->get_flags) + 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:{ + /* 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; + break; + + case IPW2100_PARAM_AUTH_ALGS: + ret = ipw2100_wpa_set_auth_algs(priv, value); + break; + + case IPW2100_PARAM_IEEE_802_1X: + priv->ieee->ieee802_1x = value; + break; + + default: + printk(KERN_ERR DRV_NAME ": %s: Unknown WPA param: %d\n", + dev->name, name); + ret = -EOPNOTSUPP; + } + + return ret; +} + +static int ipw2100_wpa_mlme(struct net_device *dev, int command, int reason) +{ + + struct ipw2100_priv *priv = ieee80211_priv(dev); + int ret = 0; + + switch (command) { + case IPW2100_MLME_STA_DEAUTH: + // silently ignore + break; + + case IPW2100_MLME_STA_DISASSOC: + ipw2100_disassociate_bssid(priv); + break; + + default: + printk(KERN_ERR DRV_NAME ": %s: Unknown MLME request: %d\n", + dev->name, command); + ret = -EOPNOTSUPP; + } + + return ret; +} + +static int ipw2100_wpa_set_wpa_ie(struct net_device *dev, + struct ipw2100_param *param, int plen) +{ + + struct ipw2100_priv *priv = ieee80211_priv(dev); + struct ieee80211_device *ieee = priv->ieee; + u8 *buf; + + if (!ieee->wpa_enabled) + return -EOPNOTSUPP; + + 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; + } + + ipw2100_wpa_assoc_frame(priv, ieee->wpa_ie, ieee->wpa_ie_len); + + return 0; +} + +/* implementation borrowed from hostap driver */ + +static int ipw2100_wpa_set_encryption(struct net_device *dev, + struct ipw2100_param *param, + int param_len) +{ + int ret = 0; + struct ipw2100_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[IPW2100_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; + } + + 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; + + 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 = IPW2100_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 = kzalloc(sizeof(struct ieee80211_crypt_data), GFP_KERNEL); + if (new_crypt == NULL) { + ret = -ENOMEM; + goto done; + } + 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 = + IPW2100_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 = IPW2100_CRYPT_ERR_KEY_SET_FAILED; + ret = -EINVAL; + goto done; + } + + 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; + } + + 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); + sec.key_sizes[param->u.crypt.idx] = + param->u.crypt.key_len; + sec.flags |= (1 << param->u.crypt.idx); + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_1; + } else if (strcmp(ops->name, "TKIP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_2; + } else if (strcmp(ops->name, "CCMP") == 0) { + sec.flags |= SEC_LEVEL; + sec.level = SEC_LEVEL_3; + } + } + 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 = IPW2100_CRYPT_ERR_CARD_CONF_FAILED; + return -EINVAL; + } + + return ret; +} + +static int ipw2100_wpa_supplicant(struct net_device *dev, struct iw_point *p) +{ + + struct ipw2100_param *param; + int ret = 0; + + IPW_DEBUG_IOCTL("wpa_supplicant: len=%d\n", p->length); + + if (p->length < sizeof(struct ipw2100_param) || !p->pointer) + return -EINVAL; + + param = (struct ipw2100_param *)kmalloc(p->length, GFP_KERNEL); + if (param == NULL) + return -ENOMEM; + + if (copy_from_user(param, p->pointer, p->length)) { + kfree(param); + return -EFAULT; + } + + switch (param->cmd) { + + case IPW2100_CMD_SET_WPA_PARAM: + ret = ipw2100_wpa_set_param(dev, param->u.wpa_param.name, + param->u.wpa_param.value); + break; + + case IPW2100_CMD_SET_WPA_IE: + ret = ipw2100_wpa_set_wpa_ie(dev, param, p->length); + break; + + case IPW2100_CMD_SET_ENCRYPTION: + ret = ipw2100_wpa_set_encryption(dev, param, p->length); + break; + + case IPW2100_CMD_MLME: + ret = ipw2100_wpa_mlme(dev, param->u.mlme.command, + param->u.mlme.reason_code); + break; + + default: + printk(KERN_ERR DRV_NAME + ": %s: Unknown WPA supplicant request: %d\n", dev->name, + param->cmd); + ret = -EOPNOTSUPP; + + } + + if (ret == 0 && copy_to_user(p->pointer, param, p->length)) + ret = -EFAULT; + + kfree(param); + return ret; +} + +static int ipw2100_ioctl(struct net_device *dev, struct ifreq *rq, int cmd) +{ + struct iwreq *wrq = (struct iwreq *)rq; + int ret = -1; + switch (cmd) { + case IPW2100_IOCTL_WPA_SUPPLICANT: + ret = ipw2100_wpa_supplicant(dev, &wrq->u.data); + return ret; + + default: + return -EOPNOTSUPP; + } + + return -EOPNOTSUPP; +} +#endif /* WIRELESS_EXT < 18 */ + static void ipw_ethtool_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info) { @@ -5914,6 +6337,9 @@ static struct net_device *ipw2100_alloc_device(struct pci_dev *pci_dev, 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; @@ -7429,6 +7855,7 @@ static int ipw2100_wx_get_power(struct net_device *dev, return 0; } +#if WIRELESS_EXT > 17 /* * WE-18 WPA support */ @@ -7690,6 +8117,7 @@ static int ipw2100_wx_set_mlme(struct net_device *dev, } return 0; } +#endif /* WIRELESS_EXT > 17 */ /* * @@ -7922,7 +8350,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 */ @@ -7946,6 +8378,7 @@ 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 */ @@ -7955,6 +8388,7 @@ static iw_handler ipw2100_wx_handlers[] = { ipw2100_wx_set_encodeext, /* SIOCSIWENCODEEXT */ ipw2100_wx_get_encodeext, /* SIOCGIWENCODEEXT */ NULL, /* SIOCSIWPMKSA */ +#endif }; #define IPW2100_PRIV_SET_MONITOR SIOCIWFIRSTPRIV diff --git a/trunk/drivers/net/wireless/ipw2200.c b/trunk/drivers/net/wireless/ipw2200.c index 4c28e332ecc3..819be2b6b7df 100644 --- a/trunk/drivers/net/wireless/ipw2200.c +++ b/trunk/drivers/net/wireless/ipw2200.c @@ -8936,12 +8936,14 @@ static int ipw_request_direct_scan(struct ipw_priv *priv, char *essid, IPW_DEBUG_HC("starting request direct scan!\n"); if (priv->status & (STATUS_SCANNING | STATUS_SCAN_ABORTING)) { - /* We should not sleep here; otherwise we will block most - * of the system (for instance, we hold rtnl_lock when we - * get here). - */ - err = -EAGAIN; - goto done; + err = wait_event_interruptible(priv->wait_state, + !(priv-> + status & (STATUS_SCANNING | + STATUS_SCAN_ABORTING))); + if (err) { + IPW_DEBUG_HC("aborting direct scan"); + goto done; + } } memset(&scan, 0, sizeof(scan)); diff --git a/trunk/drivers/net/wireless/prism54/isl_ioctl.c b/trunk/drivers/net/wireless/prism54/isl_ioctl.c index c5cd61c7f927..135a156db25d 100644 --- a/trunk/drivers/net/wireless/prism54/isl_ioctl.c +++ b/trunk/drivers/net/wireless/prism54/isl_ioctl.c @@ -748,7 +748,7 @@ prism54_get_essid(struct net_device *ndev, struct iw_request_info *info, if (essid->length) { dwrq->flags = 1; /* set ESSID to ON for Wireless Extensions */ /* if it is to big, trunk it */ - dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length); + dwrq->length = min(IW_ESSID_MAX_SIZE, essid->length + 1); } else { dwrq->flags = 0; dwrq->length = 0; diff --git a/trunk/drivers/net/wireless/prism54/islpci_eth.c b/trunk/drivers/net/wireless/prism54/islpci_eth.c index a8261d8454dd..33d64d2ee53f 100644 --- a/trunk/drivers/net/wireless/prism54/islpci_eth.c +++ b/trunk/drivers/net/wireless/prism54/islpci_eth.c @@ -177,7 +177,7 @@ islpci_eth_transmit(struct sk_buff *skb, struct net_device *ndev) #endif newskb->dev = skb->dev; - dev_kfree_skb_irq(skb); + dev_kfree_skb(skb); skb = newskb; } } diff --git a/trunk/drivers/net/wireless/ray_cs.c b/trunk/drivers/net/wireless/ray_cs.c index 7880d8c31aad..319180ca7e71 100644 --- a/trunk/drivers/net/wireless/ray_cs.c +++ b/trunk/drivers/net/wireless/ray_cs.c @@ -1256,7 +1256,7 @@ static int ray_get_essid(struct net_device *dev, extra[IW_ESSID_MAX_SIZE] = '\0'; /* Push it out ! */ - dwrq->length = strlen(extra); + dwrq->length = strlen(extra) + 1; dwrq->flags = 1; /* active */ return 0; diff --git a/trunk/drivers/net/wireless/wavelan_cs.c b/trunk/drivers/net/wireless/wavelan_cs.c index cf373625fc70..7e2039f52c49 100644 --- a/trunk/drivers/net/wireless/wavelan_cs.c +++ b/trunk/drivers/net/wireless/wavelan_cs.c @@ -2280,7 +2280,7 @@ static int wavelan_get_essid(struct net_device *dev, extra[IW_ESSID_MAX_SIZE] = '\0'; /* Set the length */ - wrqu->data.length = strlen(extra); + wrqu->data.length = strlen(extra) + 1; return 0; } diff --git a/trunk/include/net/ieee80211_crypt.h b/trunk/include/net/ieee80211_crypt.h index cd82c3e998e4..03b766afdc39 100644 --- a/trunk/include/net/ieee80211_crypt.h +++ b/trunk/include/net/ieee80211_crypt.h @@ -25,7 +25,6 @@ #include #include -#include #include enum { diff --git a/trunk/include/net/iw_handler.h b/trunk/include/net/iw_handler.h index a2c5e0b88422..d67c8393a343 100644 --- a/trunk/include/net/iw_handler.h +++ b/trunk/include/net/iw_handler.h @@ -327,7 +327,7 @@ struct iw_handler_def __u16 num_private_args; /* Array of handlers for standard ioctls - * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWCOMMIT] + * We will call dev->wireless_handlers->standard[ioctl - SIOCSIWNAME] */ const iw_handler * standard;