From fa907895b7b776208a1406efe5ba7ffe0f49f507 Mon Sep 17 00:00:00 2001 From: Matheos Worku Date: Wed, 20 Feb 2008 00:18:09 -0800 Subject: [NIU]: More BMAC alt MAC address fixes. From: Matheos Worku 1) niu_enable_alt_mac() needs to be adjusted so that the mask is computed properly for the BMAC case. 2) BMAC has 6 alt MAC addresses available, not 7. Signed-off-by: David S. Miller --- drivers/net/niu.c | 9 +++++---- drivers/net/niu.h | 2 +- 2 files changed, 6 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/net/niu.c b/drivers/net/niu.c index e98ce1e4965..d11ba61baa4 100644 --- a/drivers/net/niu.c +++ b/drivers/net/niu.c @@ -1616,12 +1616,13 @@ static int niu_enable_alt_mac(struct niu *np, int index, int on) if (index >= niu_num_alt_addr(np)) return -EINVAL; - if (np->flags & NIU_FLAGS_XMAC) + if (np->flags & NIU_FLAGS_XMAC) { reg = XMAC_ADDR_CMPEN; - else + mask = 1 << index; + } else { reg = BMAC_ADDR_CMPEN; - - mask = 1 << index; + mask = 1 << (index + 1); + } val = nr64_mac(reg); if (on) diff --git a/drivers/net/niu.h b/drivers/net/niu.h index 0e8626adc57..59dc05fcd37 100644 --- a/drivers/net/niu.h +++ b/drivers/net/niu.h @@ -499,7 +499,7 @@ #define BMAC_ADDR2 0x00110UL #define BMAC_ADDR2_ADDR2 0x000000000000ffffULL -#define BMAC_NUM_ALT_ADDR 7 +#define BMAC_NUM_ALT_ADDR 6 #define BMAC_ALT_ADDR0(NUM) (0x00118UL + (NUM)*0x18UL) #define BMAC_ALT_ADDR0_ADDR0 0x000000000000ffffULL -- cgit v1.2.3 From c15853f2c1c9baaa27bbc494cd183be96f6d9bb9 Mon Sep 17 00:00:00 2001 From: Daniel Lezcano Date: Wed, 20 Feb 2008 00:21:47 -0800 Subject: veth: fix dev refcount race When deleting the veth driver, veth_close calls netif_carrier_off for the two extremities of the network device. netif_carrier_off on the peer device will fire an event and hold a reference on the peer device. Just after, the peer is unregistered taking the rtnl_lock while the linkwatch_event is scheduled. If __linkwatch_run_queue does not occurs before the unregistering, unregister_netdevice will wait for the dev refcount to reach zero holding the rtnl_lock and linkwatch_event will wait for the rtnl_lock and hold the dev refcount. Signed-off-by: Daniel Lezcano Signed-off-by: David S. Miller --- drivers/net/veth.c | 53 ++++++++++++++++++++++++++++++++++++++++------------- 1 file changed, 40 insertions(+), 13 deletions(-) (limited to 'drivers') diff --git a/drivers/net/veth.c b/drivers/net/veth.c index 3f67a29593b..e2ad98bee6e 100644 --- a/drivers/net/veth.c +++ b/drivers/net/veth.c @@ -244,18 +244,6 @@ static int veth_open(struct net_device *dev) return 0; } -static int veth_close(struct net_device *dev) -{ - struct veth_priv *priv; - - if (netif_carrier_ok(dev)) { - priv = netdev_priv(dev); - netif_carrier_off(dev); - netif_carrier_off(priv->peer); - } - return 0; -} - static int veth_dev_init(struct net_device *dev) { struct veth_net_stats *stats; @@ -286,13 +274,50 @@ static void veth_setup(struct net_device *dev) dev->hard_start_xmit = veth_xmit; dev->get_stats = veth_get_stats; dev->open = veth_open; - dev->stop = veth_close; dev->ethtool_ops = &veth_ethtool_ops; dev->features |= NETIF_F_LLTX; dev->init = veth_dev_init; dev->destructor = veth_dev_free; } +static void veth_change_state(struct net_device *dev) +{ + struct net_device *peer; + struct veth_priv *priv; + + priv = netdev_priv(dev); + peer = priv->peer; + + if (netif_carrier_ok(peer)) { + if (!netif_carrier_ok(dev)) + netif_carrier_on(dev); + } else { + if (netif_carrier_ok(dev)) + netif_carrier_off(dev); + } +} + +static int veth_device_event(struct notifier_block *unused, + unsigned long event, void *ptr) +{ + struct net_device *dev = ptr; + + if (dev->open != veth_open) + goto out; + + switch (event) { + case NETDEV_CHANGE: + veth_change_state(dev); + break; + } +out: + return NOTIFY_DONE; +} + +static struct notifier_block veth_notifier_block __read_mostly = { + .notifier_call = veth_device_event, +}; + /* * netlink interface */ @@ -454,12 +479,14 @@ static struct rtnl_link_ops veth_link_ops = { static __init int veth_init(void) { + register_netdevice_notifier(&veth_notifier_block); return rtnl_link_register(&veth_link_ops); } static __exit void veth_exit(void) { rtnl_link_unregister(&veth_link_ops); + unregister_netdevice_notifier(&veth_notifier_block); } module_init(veth_init); -- cgit v1.2.3 From 1a17582e64dcc690a7edcd7dcf6fe89f1aa0ef97 Mon Sep 17 00:00:00 2001 From: Ivo Couckuyt Date: Wed, 20 Feb 2008 14:58:00 -0500 Subject: p54usb: add USB ID for Phillips CPWUA054 Retarget of an old patch against prism54usb in linux-wireless archive: http://marc.info/?l=linux-wireless&m=117449935810254&w=2 Cc: Ivo Couckuyt Signed-off-by: John W. Linville --- drivers/net/wireless/p54usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/p54usb.c b/drivers/net/wireless/p54usb.c index 60d286eb0b8..f8695665c0c 100644 --- a/drivers/net/wireless/p54usb.c +++ b/drivers/net/wireless/p54usb.c @@ -35,6 +35,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0707, 0xee06)}, /* SMC 2862W-G */ {USB_DEVICE(0x083a, 0x4501)}, /* Accton 802.11g WN4501 USB */ {USB_DEVICE(0x083a, 0x4502)}, /* Siemens Gigaset USB Adapter */ + {USB_DEVICE(0x083a, 0x5501)}, /* Phillips CPWUA054 */ {USB_DEVICE(0x0846, 0x4200)}, /* Netgear WG121 */ {USB_DEVICE(0x0846, 0x4210)}, /* Netgear WG121 the second ? */ {USB_DEVICE(0x0846, 0x4220)}, /* Netgear WG111 */ -- cgit v1.2.3 From 387e100ac24a6c8f2b6f4ce572098447d2893008 Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Wed, 20 Feb 2008 15:06:02 -0500 Subject: p54usb: add USB ID for Linksys WUSB54G ver 2 Based on report from Cavan Carroll : http://bugzilla.kernel.org/show_bug.cgi?id=9863 Cc: Cavan Carroll Signed-off-by: John W. Linville --- drivers/net/wireless/p54usb.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/p54usb.c b/drivers/net/wireless/p54usb.c index f8695665c0c..e7d4aee8799 100644 --- a/drivers/net/wireless/p54usb.c +++ b/drivers/net/wireless/p54usb.c @@ -63,6 +63,7 @@ static struct usb_device_id p54u_table[] __devinitdata = { {USB_DEVICE(0x0cde, 0x0008)}, /* Sagem XG703A */ {USB_DEVICE(0x0d8e, 0x3762)}, /* DLink DWL-G120 Cohiba */ {USB_DEVICE(0x09aa, 0x1000)}, /* Spinnaker Proto board */ + {USB_DEVICE(0x13b1, 0x000a)}, /* Linksys WUSB54G ver 2 */ {USB_DEVICE(0x13B1, 0x000C)}, /* Linksys WUSB54AG */ {USB_DEVICE(0x1435, 0x0427)}, /* Inventel UR054G */ {USB_DEVICE(0x2001, 0x3704)}, /* DLink DWL-G122 rev A2 */ -- cgit v1.2.3 From 65872e6b434ca463123f7d03b530f143aabc6333 Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 15 Feb 2008 21:58:51 +0100 Subject: WDEV: ath5k, fix lock imbalance Omitted lock causes sparse warning drivers/net/wireless/ath5k/base.c:1682:1: warning: context imbalance in 'ath5k_tasklet_rx' - different lock contexts for basic block Add the lock to the guilty fail path. Signed-off-by: Jiri Slaby Acked-by: Nick Kossifidis Cc: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers') diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index dfdaec02073..062d004076a 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -1715,6 +1715,7 @@ ath5k_tasklet_rx(unsigned long data) break; else if (unlikely(ret)) { ATH5K_ERR(sc, "error in processing rx descriptor\n"); + spin_unlock(&sc->rxbuflock); return; } -- cgit v1.2.3 From b988763857426020e50a19434c8434a1e08e70eb Mon Sep 17 00:00:00 2001 From: Jiri Slaby Date: Fri, 15 Feb 2008 21:58:52 +0100 Subject: WDEV, ath5k, don't return int from bool function sparse sees int -> bool cast as an error: hw.c:3754:10: warning: cast truncates bits from constant value (ffffffea becomes 0) Fix it by converting the rettype to int and check appropriately. Signed-off-by: Jiri Slaby Cc: Nick Kossifidis Cc: Luis R. Rodriguez Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/ath5k.h | 2 +- drivers/net/wireless/ath5k/base.c | 5 ++++- drivers/net/wireless/ath5k/hw.c | 8 ++++---- 3 files changed, 9 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath5k/ath5k.h b/drivers/net/wireless/ath5k/ath5k.h index c79066b38d3..69dea339261 100644 --- a/drivers/net/wireless/ath5k/ath5k.h +++ b/drivers/net/wireless/ath5k/ath5k.h @@ -1035,7 +1035,7 @@ struct ath5k_hw { unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); - bool (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *, + int (*ah_setup_xtx_desc)(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); int (*ah_proc_tx_desc)(struct ath5k_hw *, struct ath5k_desc *); diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 062d004076a..81b45b3e0f0 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -668,7 +668,10 @@ ath5k_attach(struct pci_dev *pdev, struct ieee80211_hw *hw) * return false w/o doing anything. MAC's that do * support it will return true w/o doing anything. */ - if (ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0)) + ret = ah->ah_setup_xtx_desc(ah, NULL, 0, 0, 0, 0, 0, 0); + if (ret < 0) + goto err; + if (ret > 0) __set_bit(ATH_STAT_MRRETRY, sc->status); /* diff --git a/drivers/net/wireless/ath5k/hw.c b/drivers/net/wireless/ath5k/hw.c index 1ab57aa6e4d..c2de2d958e8 100644 --- a/drivers/net/wireless/ath5k/hw.c +++ b/drivers/net/wireless/ath5k/hw.c @@ -45,7 +45,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, enum ath5k_pkt_type, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); -static bool ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *, +static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *, struct ath5k_desc *, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int, unsigned int); static int ath5k_hw_proc_4word_tx_status(struct ath5k_hw *, struct ath5k_desc *); @@ -3743,7 +3743,7 @@ static int ath5k_hw_setup_4word_tx_desc(struct ath5k_hw *ah, /* * Initialize a 4-word multirate tx descriptor on 5212 */ -static bool +static int ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, unsigned int tx_rate1, u_int tx_tries1, u_int tx_rate2, u_int tx_tries2, unsigned int tx_rate3, u_int tx_tries3) @@ -3783,10 +3783,10 @@ ath5k_hw_setup_xr_tx_desc(struct ath5k_hw *ah, struct ath5k_desc *desc, #undef _XTX_TRIES - return true; + return 1; } - return false; + return 0; } /* -- cgit v1.2.3 From 04f93a87a2db84e7214a4ec56fccd2289e973ce5 Mon Sep 17 00:00:00 2001 From: David Miller Date: Fri, 15 Feb 2008 16:08:59 -0800 Subject: ath5k: Fix build warnings on some 64-bit platforms. 'u64' is not necessarily 'unsigned long long' drivers/net/wireless/ath5k/base.c: In function 'ath5k_beacon_update_timers': drivers/net/wireless/ath5k/base.c:2130: warning: format '%llx' expects type 'long long unsigned int', but argument 4 has type 'u64' drivers/net/wireless/ath5k/base.c:2130: warning: format '%llx' expects type 'long long unsigned int', but argument 5 has type 'u64' drivers/net/wireless/ath5k/base.c: In function 'ath5k_intr': drivers/net/wireless/ath5k/base.c:2391: warning: format '%llx' expects type 'long long unsigned int', but argument 6 has type 'u64' Signed-off-by: David S. Miller Signed-off-by: John W. Linville --- drivers/net/wireless/ath5k/base.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/ath5k/base.c b/drivers/net/wireless/ath5k/base.c index 81b45b3e0f0..bef967ce34a 100644 --- a/drivers/net/wireless/ath5k/base.c +++ b/drivers/net/wireless/ath5k/base.c @@ -2130,8 +2130,9 @@ ath5k_beacon_update_timers(struct ath5k_softc *sc, u64 bc_tsf) "updated timers based on beacon TSF\n"); ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, - "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n", - bc_tsf, hw_tsf, bc_tu, hw_tu, nexttbtt); + "bc_tsf %llx hw_tsf %llx bc_tu %u hw_tu %u nexttbtt %u\n", + (unsigned long long) bc_tsf, + (unsigned long long) hw_tsf, bc_tu, hw_tu, nexttbtt); ATH5K_DBG_UNLIMIT(sc, ATH5K_DEBUG_BEACON, "intval %u %s %s\n", intval & AR5K_BEACON_PERIOD, intval & AR5K_BEACON_ENA ? "AR5K_BEACON_ENA" : "", @@ -2389,10 +2390,11 @@ ath5k_intr(int irq, void *dev_id) u64 tsf = ath5k_hw_get_tsf64(ah); sc->nexttbtt += sc->bintval; ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, - "SWBA nexttbtt: %x hw_tu: %x " - "TSF: %llx\n", - sc->nexttbtt, - TSF_TO_TU(tsf), tsf); + "SWBA nexttbtt: %x hw_tu: %x " + "TSF: %llx\n", + sc->nexttbtt, + TSF_TO_TU(tsf), + (unsigned long long) tsf); } else { ath5k_beacon_send(sc); } -- cgit v1.2.3 From 58ff70d4feae29cbb7ace410fa6585ef3afb44b6 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Mon, 18 Feb 2008 21:44:39 +0100 Subject: ssb: Fix serial console on new bcm47xx devices This fixes the baud settings for new devices like the Linksys WRT350n. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_chipcommon.c | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 6fbf1c53b6f..7cc03f2dd5a 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -376,6 +376,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc, unsigned int irq; u32 baud_base, div; u32 i, n; + unsigned int ccrev = cc->dev->id.revision; plltype = (cc->capabilities & SSB_CHIPCO_CAP_PLLT); irq = ssb_mips_irq(cc->dev); @@ -387,14 +388,39 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc, chipco_read32(cc, SSB_CHIPCO_CLOCK_M2)); div = 1; } else { - if (cc->dev->id.revision >= 11) { + if (ccrev == 20) { + /* BCM5354 uses constant 25MHz clock */ + baud_base = 25000000; + div = 48; + /* Set the override bit so we don't divide it */ + chipco_write32(cc, SSB_CHIPCO_CORECTL, + chipco_read32(cc, SSB_CHIPCO_CORECTL) + | SSB_CHIPCO_CORECTL_UARTCLK0); + } else if ((ccrev >= 11) && (ccrev != 15)) { /* Fixed ALP clock */ baud_base = 20000000; + if (cc->capabilities & SSB_CHIPCO_CAP_PMU) { + /* FIXME: baud_base is different for devices with a PMU */ + SSB_WARN_ON(1); + } div = 1; + if (ccrev >= 21) { + /* Turn off UART clock before switching clocksource. */ + chipco_write32(cc, SSB_CHIPCO_CORECTL, + chipco_read32(cc, SSB_CHIPCO_CORECTL) + & ~SSB_CHIPCO_CORECTL_UARTCLKEN); + } /* Set the override bit so we don't divide it */ chipco_write32(cc, SSB_CHIPCO_CORECTL, - SSB_CHIPCO_CORECTL_UARTCLK0); - } else if (cc->dev->id.revision >= 3) { + chipco_read32(cc, SSB_CHIPCO_CORECTL) + | SSB_CHIPCO_CORECTL_UARTCLK0); + if (ccrev >= 21) { + /* Re-enable the UART clock. */ + chipco_write32(cc, SSB_CHIPCO_CORECTL, + chipco_read32(cc, SSB_CHIPCO_CORECTL) + | SSB_CHIPCO_CORECTL_UARTCLKEN); + } + } else if (ccrev >= 3) { /* Internal backplane clock */ baud_base = ssb_clockspeed(bus); div = chipco_read32(cc, SSB_CHIPCO_CLKDIV) @@ -406,7 +432,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc, } /* Clock source depends on strapping if UartClkOverride is unset */ - if ((cc->dev->id.revision > 0) && + if ((ccrev > 0) && !(chipco_read32(cc, SSB_CHIPCO_CORECTL) & SSB_CHIPCO_CORECTL_UARTCLK0)) { if ((cc->capabilities & SSB_CHIPCO_CAP_UARTCLK) == SSB_CHIPCO_CAP_UARTCLK_INT) { @@ -428,7 +454,7 @@ int ssb_chipco_serial_init(struct ssb_chipcommon *cc, cc_mmio = cc->dev->bus->mmio + (cc->dev->core_index * SSB_CORE_SIZE); uart_regs = cc_mmio + SSB_CHIPCO_UART0_DATA; /* Offset changed at after rev 0 */ - if (cc->dev->id.revision == 0) + if (ccrev == 0) uart_regs += (i * 8); else uart_regs += (i * 256); -- cgit v1.2.3 From 42bfad4f71637c4eb4791aa8062063c4a8526522 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 19 Feb 2008 12:41:30 +0100 Subject: ssb: Fix watchdog access for devices without a chipcommon This fixes the SSB watchdog access for devices without a chipcommon. These devices have the watchdog on the extif. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/Kconfig | 6 ++++++ drivers/ssb/Makefile | 1 + drivers/ssb/driver_extif.c | 6 ++++++ drivers/ssb/embedded.c | 26 ++++++++++++++++++++++++++ 4 files changed, 39 insertions(+) create mode 100644 drivers/ssb/embedded.c (limited to 'drivers') diff --git a/drivers/ssb/Kconfig b/drivers/ssb/Kconfig index d976660cb7f..78fd33125e0 100644 --- a/drivers/ssb/Kconfig +++ b/drivers/ssb/Kconfig @@ -105,6 +105,12 @@ config SSB_DRIVER_MIPS If unsure, say N +# Assumption: We are on embedded, if we compile the MIPS core. +config SSB_EMBEDDED + bool + depends on SSB_DRIVER_MIPS + default y + config SSB_DRIVER_EXTIF bool "SSB Broadcom EXTIF core driver (EXPERIMENTAL)" depends on SSB_DRIVER_MIPS && EXPERIMENTAL diff --git a/drivers/ssb/Makefile b/drivers/ssb/Makefile index 7be39759580..e235144add7 100644 --- a/drivers/ssb/Makefile +++ b/drivers/ssb/Makefile @@ -1,5 +1,6 @@ # core ssb-y += main.o scan.o +ssb-$(CONFIG_SSB_EMBEDDED) += embedded.o # host support ssb-$(CONFIG_SSB_PCIHOST) += pci.o pcihost_wrapper.o diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c index fe55eb8b038..b1899f422a5 100644 --- a/drivers/ssb/driver_extif.c +++ b/drivers/ssb/driver_extif.c @@ -110,6 +110,12 @@ void ssb_extif_get_clockcontrol(struct ssb_extif *extif, *m = extif_read32(extif, SSB_EXTIF_CLOCK_SB); } +void ssb_extif_watchdog_timer_set(struct ssb_extif *extif, + u32 ticks) +{ + extif_write32(extif, SSB_EXTIF_WATCHDOG, ticks); +} + u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) { return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c new file mode 100644 index 00000000000..751f58ac612 --- /dev/null +++ b/drivers/ssb/embedded.c @@ -0,0 +1,26 @@ +/* + * Sonics Silicon Backplane + * Embedded systems support code + * + * Copyright 2005-2008, Broadcom Corporation + * Copyright 2006-2008, Michael Buesch + * + * Licensed under the GNU/GPL. See COPYING for details. + */ + +#include +#include + + +int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks) +{ + if (ssb_chipco_available(&bus->chipco)) { + ssb_chipco_watchdog_timer_set(&bus->chipco, ticks); + return 0; + } + if (ssb_extif_available(&bus->extif)) { + ssb_extif_watchdog_timer_set(&bus->extif, ticks); + return 0; + } + return -ENODEV; +} -- cgit v1.2.3 From c2bcbe65fc88d61f9a806367ff6eab76c9eabb3a Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 19 Feb 2008 14:53:35 +0100 Subject: ssb: Fix the GPIO API This fixes the GPIO API to be usable. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_chipcommon.c | 35 +++++++++++++++++++++++++++++------ drivers/ssb/driver_extif.c | 24 ++++++++++++++++++++---- 2 files changed, 49 insertions(+), 10 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 7cc03f2dd5a..7ea0c0faa9a 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -39,12 +39,14 @@ static inline void chipco_write32(struct ssb_chipcommon *cc, ssb_write32(cc->dev, offset, value); } -static inline void chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset, - u32 mask, u32 value) +static inline u32 chipco_write32_masked(struct ssb_chipcommon *cc, u16 offset, + u32 mask, u32 value) { value &= mask; value |= chipco_read32(cc, offset) & ~mask; chipco_write32(cc, offset, value); + + return value; } void ssb_chipco_set_clockmode(struct ssb_chipcommon *cc, @@ -355,16 +357,37 @@ u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask) { return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask; } +EXPORT_SYMBOL(ssb_chipco_gpio_in); + +u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) +{ + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); +} +EXPORT_SYMBOL(ssb_chipco_gpio_out); + +u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) +{ + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); +} +EXPORT_SYMBOL(ssb_chipco_gpio_outen); + +u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value) +{ + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); +} +EXPORT_SYMBOL(ssb_chipco_gpio_control); -void ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) +u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) { - chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); } +EXPORT_SYMBOL(ssb_chipco_gpio_intmask); -void ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) +u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value) { - chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); + return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); } +EXPORT_SYMBOL(ssb_chipco_gpio_polarity); #ifdef CONFIG_SSB_SERIAL int ssb_chipco_serial_init(struct ssb_chipcommon *cc, diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c index b1899f422a5..10c6b287f8b 100644 --- a/drivers/ssb/driver_extif.c +++ b/drivers/ssb/driver_extif.c @@ -27,12 +27,14 @@ static inline void extif_write32(struct ssb_extif *extif, u16 offset, u32 value) ssb_write32(extif->dev, offset, value); } -static inline void extif_write32_masked(struct ssb_extif *extif, u16 offset, - u32 mask, u32 value) +static inline u32 extif_write32_masked(struct ssb_extif *extif, u16 offset, + u32 mask, u32 value) { value &= mask; value |= extif_read32(extif, offset) & ~mask; extif_write32(extif, offset, value); + + return value; } #ifdef CONFIG_SSB_SERIAL @@ -120,16 +122,30 @@ u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) { return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; } +EXPORT_SYMBOL(ssb_extif_gpio_in); -void ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) +u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), mask, value); } +EXPORT_SYMBOL(ssb_extif_gpio_out); -void ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) +u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), mask, value); } +EXPORT_SYMBOL(ssb_extif_gpio_outen); + +u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) +{ + return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); +} +EXPORT_SYMBOL(ssb_extif_gpio_polarity); +u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) +{ + return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); +} +EXPORT_SYMBOL(ssb_extif_gpio_intmask); -- cgit v1.2.3 From 53521d8c90d366191b6c134f88a8ebe83de60614 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 19 Feb 2008 16:22:50 +0100 Subject: ssb: Make the GPIO API reentrancy safe This fixes the GPIO API to be reentrancy safe. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_chipcommon.c | 6 --- drivers/ssb/driver_extif.c | 5 -- drivers/ssb/embedded.c | 106 ++++++++++++++++++++++++++++++++++++++++ drivers/ssb/main.c | 3 ++ 4 files changed, 109 insertions(+), 11 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/driver_chipcommon.c b/drivers/ssb/driver_chipcommon.c index 7ea0c0faa9a..e586321a473 100644 --- a/drivers/ssb/driver_chipcommon.c +++ b/drivers/ssb/driver_chipcommon.c @@ -357,37 +357,31 @@ u32 ssb_chipco_gpio_in(struct ssb_chipcommon *cc, u32 mask) { return chipco_read32(cc, SSB_CHIPCO_GPIOIN) & mask; } -EXPORT_SYMBOL(ssb_chipco_gpio_in); u32 ssb_chipco_gpio_out(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUT, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_out); u32 ssb_chipco_gpio_outen(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOOUTEN, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_outen); u32 ssb_chipco_gpio_control(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOCTL, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_control); u32 ssb_chipco_gpio_intmask(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOIRQ, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_intmask); u32 ssb_chipco_gpio_polarity(struct ssb_chipcommon *cc, u32 mask, u32 value) { return chipco_write32_masked(cc, SSB_CHIPCO_GPIOPOL, mask, value); } -EXPORT_SYMBOL(ssb_chipco_gpio_polarity); #ifdef CONFIG_SSB_SERIAL int ssb_chipco_serial_init(struct ssb_chipcommon *cc, diff --git a/drivers/ssb/driver_extif.c b/drivers/ssb/driver_extif.c index 10c6b287f8b..c3e1d3e6d61 100644 --- a/drivers/ssb/driver_extif.c +++ b/drivers/ssb/driver_extif.c @@ -122,30 +122,25 @@ u32 ssb_extif_gpio_in(struct ssb_extif *extif, u32 mask) { return extif_read32(extif, SSB_EXTIF_GPIO_IN) & mask; } -EXPORT_SYMBOL(ssb_extif_gpio_in); u32 ssb_extif_gpio_out(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUT(0), mask, value); } -EXPORT_SYMBOL(ssb_extif_gpio_out); u32 ssb_extif_gpio_outen(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_OUTEN(0), mask, value); } -EXPORT_SYMBOL(ssb_extif_gpio_outen); u32 ssb_extif_gpio_polarity(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTPOL, mask, value); } -EXPORT_SYMBOL(ssb_extif_gpio_polarity); u32 ssb_extif_gpio_intmask(struct ssb_extif *extif, u32 mask, u32 value) { return extif_write32_masked(extif, SSB_EXTIF_GPIO_INTMASK, mask, value); } -EXPORT_SYMBOL(ssb_extif_gpio_intmask); diff --git a/drivers/ssb/embedded.c b/drivers/ssb/embedded.c index 751f58ac612..d3ade821555 100644 --- a/drivers/ssb/embedded.c +++ b/drivers/ssb/embedded.c @@ -11,6 +11,8 @@ #include #include +#include "ssb_private.h" + int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks) { @@ -24,3 +26,107 @@ int ssb_watchdog_timer_set(struct ssb_bus *bus, u32 ticks) } return -ENODEV; } + +u32 ssb_gpio_in(struct ssb_bus *bus, u32 mask) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_in(&bus->chipco, mask); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_in(&bus->extif, mask); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_in); + +u32 ssb_gpio_out(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_out(&bus->chipco, mask, value); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_out(&bus->extif, mask, value); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_out); + +u32 ssb_gpio_outen(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_outen(&bus->chipco, mask, value); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_outen(&bus->extif, mask, value); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_outen); + +u32 ssb_gpio_control(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_control(&bus->chipco, mask, value); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_control); + +u32 ssb_gpio_intmask(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_intmask(&bus->chipco, mask, value); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_intmask(&bus->extif, mask, value); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_intmask); + +u32 ssb_gpio_polarity(struct ssb_bus *bus, u32 mask, u32 value) +{ + unsigned long flags; + u32 res = 0; + + spin_lock_irqsave(&bus->gpio_lock, flags); + if (ssb_chipco_available(&bus->chipco)) + res = ssb_chipco_gpio_polarity(&bus->chipco, mask, value); + else if (ssb_extif_available(&bus->extif)) + res = ssb_extif_gpio_polarity(&bus->extif, mask, value); + else + SSB_WARN_ON(1); + spin_unlock_irqrestore(&bus->gpio_lock, flags); + + return res; +} +EXPORT_SYMBOL(ssb_gpio_polarity); diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index 9028ed5715a..af07ab22708 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -569,6 +569,9 @@ static int ssb_bus_register(struct ssb_bus *bus, spin_lock_init(&bus->bar_lock); INIT_LIST_HEAD(&bus->list); +#ifdef CONFIG_SSB_EMBEDDED + spin_lock_init(&bus->gpio_lock); +#endif /* Powerup the bus */ err = ssb_pci_xtal(bus, SSB_GPIO_XTAL | SSB_GPIO_PLL, 1); -- cgit v1.2.3 From 7cb4461520f307a6e3fb2bb32cb8daee45aa1fae Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Tue, 19 Feb 2008 17:46:48 +0100 Subject: ssb: Fix pcicore cardbus mode This fixes the pcicore driver to not die a horrible crash death when inserting a cardbus card. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_pcicore.c | 28 ++++++++++++++++++++++++++-- drivers/ssb/main.c | 1 + 2 files changed, 27 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 2faaa906d5d..059452fbb16 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -11,6 +11,7 @@ #include #include #include +#include #include "ssb_private.h" @@ -27,6 +28,18 @@ void pcicore_write32(struct ssb_pcicore *pc, u16 offset, u32 value) ssb_write32(pc->dev, offset, value); } +static inline +u16 pcicore_read16(struct ssb_pcicore *pc, u16 offset) +{ + return ssb_read16(pc->dev, offset); +} + +static inline +void pcicore_write16(struct ssb_pcicore *pc, u16 offset, u16 value) +{ + ssb_write16(pc->dev, offset, value); +} + /************************************************** * Code for hostmode operation. **************************************************/ @@ -117,8 +130,10 @@ static u32 get_cfgspace_addr(struct ssb_pcicore *pc, u32 addr = 0; u32 tmp; - if (unlikely(pc->cardbusmode && dev > 1)) + /* We do only have one cardbus device behind the bridge. */ + if (pc->cardbusmode && (dev >= 1)) goto out; + if (bus == 0) { /* Type 0 transaction */ if (unlikely(dev >= SSB_PCI_SLOT_MAX)) @@ -318,7 +333,16 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) pcicore_write32(pc, SSB_PCICORE_ARBCTL, val); udelay(1); /* Assertion time demanded by the PCI standard */ - /*TODO cardbus mode */ + if (pc->dev->bus->has_cardbus_slot) { + ssb_dprintk(KERN_INFO PFX "CardBus slot detected\n"); + pc->cardbusmode = 1; + /* GPIO 1 resets the bridge */ + ssb_gpio_out(pc->dev->bus, 1, 1); + ssb_gpio_outen(pc->dev->bus, 1, 1); + pcicore_write16(pc, SSB_PCICORE_SPROM(0), + pcicore_read16(pc, SSB_PCICORE_SPROM(0)) + | 0x0400); + } /* 64MB I/O window */ pcicore_write32(pc, SSB_PCICORE_SBTOPCI0, diff --git a/drivers/ssb/main.c b/drivers/ssb/main.c index af07ab22708..bedb2b4ee9d 100644 --- a/drivers/ssb/main.c +++ b/drivers/ssb/main.c @@ -557,6 +557,7 @@ static int ssb_fetch_invariants(struct ssb_bus *bus, goto out; memcpy(&bus->boardinfo, &iv.boardinfo, sizeof(iv.boardinfo)); memcpy(&bus->sprom, &iv.sprom, sizeof(iv.sprom)); + bus->has_cardbus_slot = iv.has_cardbus_slot; out: return err; } -- cgit v1.2.3 From 1955fd0b533d05828bff7ed290213d2a0fc0f04f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Feb 2008 12:05:59 +0100 Subject: rtl818x: fix sparse warnings This silences a few sparse warnings. There are two more where I can't follow the code. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/rtl8180_dev.c | 4 +++- drivers/net/wireless/rtl8187_dev.c | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/rtl8180_dev.c b/drivers/net/wireless/rtl8180_dev.c index 27ebd689aa2..5e9a8ace0d8 100644 --- a/drivers/net/wireless/rtl8180_dev.c +++ b/drivers/net/wireless/rtl8180_dev.c @@ -135,13 +135,15 @@ static void rtl8180_handle_tx(struct ieee80211_hw *dev, unsigned int prio) while (skb_queue_len(&ring->queue)) { struct rtl8180_tx_desc *entry = &ring->desc[ring->idx]; struct sk_buff *skb; - struct ieee80211_tx_status status = { {0} }; + struct ieee80211_tx_status status; struct ieee80211_tx_control *control; u32 flags = le32_to_cpu(entry->flags); if (flags & RTL8180_TX_DESC_FLAG_OWN) return; + memset(&status, 0, sizeof(status)); + ring->idx = (ring->idx + 1) % ring->entries; skb = __skb_dequeue(&ring->queue); pci_unmap_single(priv->pdev, le32_to_cpu(entry->tx_buf), diff --git a/drivers/net/wireless/rtl8187_dev.c b/drivers/net/wireless/rtl8187_dev.c index 0d71716d750..f44505994a0 100644 --- a/drivers/net/wireless/rtl8187_dev.c +++ b/drivers/net/wireless/rtl8187_dev.c @@ -113,10 +113,12 @@ void rtl8187_write_phy(struct ieee80211_hw *dev, u8 addr, u32 data) static void rtl8187_tx_cb(struct urb *urb) { - struct ieee80211_tx_status status = { {0} }; + struct ieee80211_tx_status status; struct sk_buff *skb = (struct sk_buff *)urb->context; struct rtl8187_tx_info *info = (struct rtl8187_tx_info *)skb->cb; + memset(&status, 0, sizeof(status)); + usb_free_urb(info->urb); if (info->control) memcpy(&status.control, info->control, sizeof(status.control)); -- cgit v1.2.3 From 5078ed50712aa3df1099540b524d01075aee653f Mon Sep 17 00:00:00 2001 From: Johannes Berg Date: Wed, 20 Feb 2008 12:09:25 +0100 Subject: zd1211rw: fix sparse warnings This silences sparse when run on zd1211rw. Signed-off-by: Johannes Berg Signed-off-by: John W. Linville --- drivers/net/wireless/zd1211rw/zd_mac.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'drivers') diff --git a/drivers/net/wireless/zd1211rw/zd_mac.c b/drivers/net/wireless/zd1211rw/zd_mac.c index 49127e4b42c..76ef2d83919 100644 --- a/drivers/net/wireless/zd1211rw/zd_mac.c +++ b/drivers/net/wireless/zd1211rw/zd_mac.c @@ -360,11 +360,14 @@ void zd_mac_tx_failed(struct ieee80211_hw *hw) { struct sk_buff_head *q = &zd_hw_mac(hw)->ack_wait_queue; struct sk_buff *skb; - struct ieee80211_tx_status status = {{0}}; + struct ieee80211_tx_status status; skb = skb_dequeue(q); if (skb == NULL) return; + + memset(&status, 0, sizeof(status)); + tx_status(hw, skb, &status, 0); } @@ -389,7 +392,8 @@ void zd_mac_tx_to_dev(struct sk_buff *skb, int error) if (unlikely(error || (cb->control->flags & IEEE80211_TXCTL_NO_ACK))) { - struct ieee80211_tx_status status = {{0}}; + struct ieee80211_tx_status status; + memset(&status, 0, sizeof(status)); tx_status(hw, skb, &status, !error); } else { struct sk_buff_head *q = @@ -603,7 +607,9 @@ static int filter_ack(struct ieee80211_hw *hw, struct ieee80211_hdr *rx_hdr, tx_hdr = (struct ieee80211_hdr *)skb->data; if (likely(!compare_ether_addr(tx_hdr->addr2, rx_hdr->addr1))) { - struct ieee80211_tx_status status = {{0}}; + struct ieee80211_tx_status status; + + memset(&status, 0, sizeof(status)); status.flags = IEEE80211_TX_STATUS_ACK; status.ack_signal = stats->ssi; __skb_unlink(skb, q); -- cgit v1.2.3 From fc71acc846c577473ada72a46c5ea9c935eca086 Mon Sep 17 00:00:00 2001 From: Michael Buesch Date: Sat, 16 Feb 2008 18:13:36 +0100 Subject: ssb: Fix support for PCI devices behind a SSB->PCI bridge We must pin all resources and make sure the PCI subsystem won't relocate us, as the addresses are hardwired into hardware. Signed-off-by: Michael Buesch Signed-off-by: John W. Linville --- drivers/ssb/driver_pcicore.c | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) (limited to 'drivers') diff --git a/drivers/ssb/driver_pcicore.c b/drivers/ssb/driver_pcicore.c index 059452fbb16..6d99a988005 100644 --- a/drivers/ssb/driver_pcicore.c +++ b/drivers/ssb/driver_pcicore.c @@ -79,6 +79,7 @@ int pcibios_plat_dev_init(struct pci_dev *d) base = &ssb_pcicore_pcibus_iobase; else base = &ssb_pcicore_pcibus_membase; + res->flags |= IORESOURCE_PCI_FIXED; if (res->end) { size = res->end - res->start + 1; if (*base & (size - 1)) @@ -101,10 +102,12 @@ int pcibios_plat_dev_init(struct pci_dev *d) static void __init ssb_fixup_pcibridge(struct pci_dev *dev) { + u8 lat; + if (dev->bus->number != 0 || PCI_SLOT(dev->devfn) != 0) return; - ssb_printk(KERN_INFO "PCI: fixing up bridge\n"); + ssb_printk(KERN_INFO "PCI: Fixing up bridge %s\n", pci_name(dev)); /* Enable PCI bridge bus mastering and memory space */ pci_set_master(dev); @@ -114,7 +117,10 @@ static void __init ssb_fixup_pcibridge(struct pci_dev *dev) pci_write_config_dword(dev, SSB_BAR1_CONTROL, 3); /* Make sure our latency is high enough to handle the devices behind us */ - pci_write_config_byte(dev, PCI_LATENCY_TIMER, 0xa8); + lat = 168; + ssb_printk(KERN_INFO "PCI: Fixing latency timer of device %s to %u\n", + pci_name(dev), lat); + pci_write_config_byte(dev, PCI_LATENCY_TIMER, lat); } DECLARE_PCI_FIXUP_EARLY(PCI_ANY_ID, PCI_ANY_ID, ssb_fixup_pcibridge); @@ -294,14 +300,14 @@ static struct resource ssb_pcicore_mem_resource = { .name = "SSB PCIcore external memory", .start = SSB_PCI_DMA, .end = SSB_PCI_DMA + SSB_PCI_DMA_SZ - 1, - .flags = IORESOURCE_MEM, + .flags = IORESOURCE_MEM | IORESOURCE_PCI_FIXED, }; static struct resource ssb_pcicore_io_resource = { .name = "SSB PCIcore external I/O", .start = 0x100, .end = 0x7FF, - .flags = IORESOURCE_IO, + .flags = IORESOURCE_IO | IORESOURCE_PCI_FIXED, }; static struct pci_controller ssb_pcicore_controller = { @@ -368,7 +374,8 @@ static void ssb_pcicore_init_hostmode(struct ssb_pcicore *pc) /* Ok, ready to run, register it to the system. * The following needs change, if we want to port hostmode * to non-MIPS platform. */ - set_io_port_base((unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000)); + ssb_pcicore_controller.io_map_base = (unsigned long)ioremap_nocache(SSB_PCI_MEM, 0x04000000); + set_io_port_base(ssb_pcicore_controller.io_map_base); /* Give some time to the PCI controller to configure itself with the new * values. Not waiting at this point causes crashes of the machine. */ mdelay(10); -- cgit v1.2.3 From a2724e2559a3c41ac6182da6e2446d3abf0720a5 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 23 Feb 2008 19:47:44 -0800 Subject: [BNX2]: More 5706S link down workaround. The previous patches to workaround the 5706S on an HP blade were not sufficient. The link state still does not change properly in some cases. This patch adds polling to make it completely reliable. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 32 +++++++++++++++++--------------- 1 file changed, 17 insertions(+), 15 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 471c7f3e8a4..2fa25805096 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -1273,14 +1273,20 @@ bnx2_set_link(struct bnx2 *bp) if ((bp->phy_flags & BNX2_PHY_FLAG_SERDES) && (CHIP_NUM(bp) == CHIP_NUM_5706)) { - u32 val; + u32 val, an_dbg; if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) { bnx2_5706s_force_link_dn(bp, 0); bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN; } val = REG_RD(bp, BNX2_EMAC_STATUS); - if (val & BNX2_EMAC_STATUS_LINK) + + bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG); + bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg); + bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &an_dbg); + + if ((val & BNX2_EMAC_STATUS_LINK) && + !(an_dbg & MISC_SHDW_AN_DBG_NOSYNC)) bmsr |= BMSR_LSTATUS; else bmsr &= ~BMSR_LSTATUS; @@ -5390,13 +5396,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) int check_link = 1; spin_lock(&bp->phy_lock); - if (bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN) { - bnx2_5706s_force_link_dn(bp, 0); - bp->phy_flags &= ~BNX2_PHY_FLAG_FORCED_DOWN; - spin_unlock(&bp->phy_lock); - return; - } - if (bp->serdes_an_pending) { bp->serdes_an_pending--; check_link = 0; @@ -5420,7 +5419,6 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) (bp->phy_flags & BNX2_PHY_FLAG_PARALLEL_DETECT)) { u32 phy2; - check_link = 0; bnx2_write_phy(bp, 0x17, 0x0f01); bnx2_read_phy(bp, 0x15, &phy2); if (phy2 & 0x20) { @@ -5435,17 +5433,21 @@ bnx2_5706_serdes_timer(struct bnx2 *bp) } else bp->current_interval = bp->timer_interval; - if (bp->link_up && (bp->autoneg & AUTONEG_SPEED) && check_link) { + if (check_link) { u32 val; bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_AN_DBG); bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val); bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &val); - if (val & MISC_SHDW_AN_DBG_NOSYNC) { - bnx2_5706s_force_link_dn(bp, 1); - bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN; - } + if (bp->link_up && (val & MISC_SHDW_AN_DBG_NOSYNC)) { + if (!(bp->phy_flags & BNX2_PHY_FLAG_FORCED_DOWN)) { + bnx2_5706s_force_link_dn(bp, 1); + bp->phy_flags |= BNX2_PHY_FLAG_FORCED_DOWN; + } else + bnx2_set_link(bp); + } else if (!bp->link_up && !(val & MISC_SHDW_AN_DBG_NOSYNC)) + bnx2_set_link(bp); } spin_unlock(&bp->phy_lock); } -- cgit v1.2.3 From 38ea3686f6d1110a3787dfd7c5cf7bad1926818b Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 23 Feb 2008 19:48:57 -0800 Subject: [BNX2]: Disable parallel detect on an HP blade. Because of some board issues, we need to disable parallel detect on an HP blade. Without this patch, the link state can become stuck when it goes into parallel detect mode. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 14 +++++++++++++- drivers/net/bnx2.h | 1 + 2 files changed, 14 insertions(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 2fa25805096..35356fba5a7 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -5362,11 +5362,15 @@ bnx2_test_intr(struct bnx2 *bp) return -ENODEV; } +/* Determining link for parallel detection. */ static int bnx2_5706_serdes_has_link(struct bnx2 *bp) { u32 mode_ctl, an_dbg, exp; + if (bp->phy_flags & BNX2_PHY_FLAG_NO_PARALLEL) + return 0; + bnx2_write_phy(bp, MII_BNX2_MISC_SHADOW, MISC_SHDW_MODE_CTL); bnx2_read_phy(bp, MII_BNX2_MISC_SHADOW, &mode_ctl); @@ -7328,7 +7332,15 @@ bnx2_init_board(struct pci_dev *pdev, struct net_device *dev) bp->flags |= BNX2_FLAG_NO_WOL; bp->wol = 0; } - if (CHIP_NUM(bp) != CHIP_NUM_5706) { + if (CHIP_NUM(bp) == CHIP_NUM_5706) { + /* Don't do parallel detect on this board because of + * some board problems. The link will not go down + * if we do parallel detect. + */ + if (pdev->subsystem_vendor == PCI_VENDOR_ID_HP && + pdev->subsystem_device == 0x310c) + bp->phy_flags |= BNX2_PHY_FLAG_NO_PARALLEL; + } else { bp->phy_addr = 2; if (reg & BNX2_SHARED_HW_CFG_PHY_2_5G) bp->phy_flags |= BNX2_PHY_FLAG_2_5G_CAPABLE; diff --git a/drivers/net/bnx2.h b/drivers/net/bnx2.h index 3aa0364942e..1eaf5bb3d9c 100644 --- a/drivers/net/bnx2.h +++ b/drivers/net/bnx2.h @@ -6673,6 +6673,7 @@ struct bnx2 { #define BNX2_PHY_FLAG_DIS_EARLY_DAC 0x00000400 #define BNX2_PHY_FLAG_REMOTE_PHY_CAP 0x00000800 #define BNX2_PHY_FLAG_FORCED_DOWN 0x00001000 +#define BNX2_PHY_FLAG_NO_PARALLEL 0x00002000 u32 mii_bmcr; u32 mii_bmsr; -- cgit v1.2.3 From c73b1d1f26d4c9d54b49526edf9ee958ee5b80c1 Mon Sep 17 00:00:00 2001 From: Michael Chan Date: Sat, 23 Feb 2008 19:49:48 -0800 Subject: [BNX2]: Update version to 1.7.4. Signed-off-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/bnx2.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers') diff --git a/drivers/net/bnx2.c b/drivers/net/bnx2.c index 35356fba5a7..15853be4680 100644 --- a/drivers/net/bnx2.c +++ b/drivers/net/bnx2.c @@ -56,8 +56,8 @@ #define DRV_MODULE_NAME "bnx2" #define PFX DRV_MODULE_NAME ": " -#define DRV_MODULE_VERSION "1.7.3" -#define DRV_MODULE_RELDATE "January 29, 2008" +#define DRV_MODULE_VERSION "1.7.4" +#define DRV_MODULE_RELDATE "February 18, 2008" #define RUN_AT(x) (jiffies + (x)) -- cgit v1.2.3 From 759afc31332aed66bde20743e7e2d1e47b08aaeb Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Sat, 23 Feb 2008 19:51:59 -0800 Subject: tg3: ethtool phys_id default When asked to blink LEDs the tg3 driver behaves when using: ethtool -p ethX The default value for data is zero, and other drivers interpret this as blink forever (or at least a really long time). The tg3 driver interprets this as blink once. All drivers should have the same behaviour. Signed-off-by: Stephen Hemminger Acked-by: Michael Chan Signed-off-by: David S. Miller --- drivers/net/tg3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers') diff --git a/drivers/net/tg3.c b/drivers/net/tg3.c index db606b60388..26ffb67f1da 100644 --- a/drivers/net/tg3.c +++ b/drivers/net/tg3.c @@ -8781,7 +8781,7 @@ static int tg3_phys_id(struct net_device *dev, u32 data) return -EAGAIN; if (data == 0) - data = 2; + data = UINT_MAX / 2; for (i = 0; i < (data * 2); i++) { if ((i % 2) == 0) -- cgit v1.2.3