* Re: [PATCH 07/18 v2] isdn: avm: call disable_pci_device() if pci_probe() failed
From: David Miller @ 2010-08-10 8:43 UTC (permalink / raw)
To: segooon; +Cc: kernel-janitors, isdn, adobriyan, tilman, netdev
In-Reply-To: <1281383448-14050-1-git-send-email-segooon@gmail.com>
From: Kulikov Vasiliy <segooon@gmail.com>
Date: Mon, 9 Aug 2010 23:50:47 +0400
> Driver should call disable_pci_device() if it returns from pci_probe()
> with error.
>
> Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
Applied, but as previously mentioned disable_pci_device() is wrong.
^ permalink raw reply
* Re: [PATCH 09/18 v2] isdn: mISDN: call disable_pci_device() if pci_probe() failed
From: David Miller @ 2010-08-10 8:43 UTC (permalink / raw)
To: segooon
Cc: kernel-janitors, isdn, akpm, u.kleine-koenig, peterhuewe, tj,
netdev
In-Reply-To: <1281383456-14119-1-git-send-email-segooon@gmail.com>
From: Kulikov Vasiliy <segooon@gmail.com>
Date: Mon, 9 Aug 2010 23:50:53 +0400
> Driver should call disable_pci_device() if it returns from pci_probe()
> with error.
>
> Signed-off-by: Kulikov Vasiliy <segooon@gmail.com>
Also applied, and likewise disable_pci_device() needed to be fixed up.
^ permalink raw reply
* Re: [net-next] net: Use NET_XMIT_SUCCESS where possible.
From: David Miller @ 2010-08-10 8:45 UTC (permalink / raw)
To: greearb; +Cc: netdev
In-Reply-To: <1281379438-2709-1-git-send-email-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Date: Mon, 9 Aug 2010 11:43:58 -0700
> This is based on work originally done by Patric McHardy.
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v2] net: add Fast Ethernet driver for PXA168.
From: Sachin Sanap @ 2010-08-10 8:30 UTC (permalink / raw)
To: Philip Rakity
Cc: Lennert Buytenhek, netdev@vger.kernel.org, Ashish Karkare,
Prabhanjan Sarnaik, eric.y.miao@gmail.com, Mark Brown
In-Reply-To: <FE9BFA4C-11AB-46B9-A514-EB62467A1BB7@marvell.com>
>From 97021af9bc8cb3f4ea9eacaee45e5c9f5d85c9c3 Mon Sep 17 00:00:00 2001
From: Sachin Sanap <ssanap@marvell.com>
Date: Sat, 7 Aug 2010 01:38:46 +0530
Subject: [PATCH] net: add Fast Ethernet driver for PXA168.
Signed-off-by: Sachin Sanap <ssanap@marvell.com>
---
V2:
* Modified the code for endian-cleanness.addr_table_entry variables are now
declared as __le32 and appropriate cpu_to_le32/le32_to_cpu conversions
are used. Code is parsed through sparse with zero errors/warnings.But
its not tested on actual Big-endian configuration.
* Modified the hash calculation function and made it more readable, also added
comments wherever required.
* Moved the pxa168_eth.h file in include/linux.
* Removed the TX_DONE_INTERVAL constant and now the tx done interval is fired
on every (tx_ring_size / 4).
* Headroom in SKB for 802.11 not included in the patch since that varies based
on 802.11 a/b/g/n.
* MISC changes:
* Added comments as to why (init) call back is required.
* Changed the speed,duplex and phy_addr to int type.
* "config PXA168_ETH" now "depends on CPU_PXA168".
* Removed the Marvell OUI and added random_ether_addr.
* Removed the address alignment code since dma_alloc_coherent already aligns
it.
* Misc coding style changes.
drivers/net/Kconfig | 10 +
drivers/net/Makefile | 1 +
drivers/net/pxa168_eth.c | 1569 ++++++++++++++++++++++++++++++++++++++++++++
include/linux/pxa168_eth.h | 20 +
4 files changed, 1600 insertions(+), 0 deletions(-)
create mode 100644 drivers/net/pxa168_eth.c
create mode 100644 include/linux/pxa168_eth.h
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index ce2fcdd..78cd7e8 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -927,6 +927,16 @@ config SMC91X
The module will be called smc91x. If you want to compile it as a
module, say M here and read <file:Documentation/kbuild/modules.txt>.
+config PXA168_ETH
+ tristate "Marvell pxa168 ethernet support"
+ depends on CPU_PXA168
+ select PHYLIB
+ help
+ This driver supports the pxa168 Ethernet ports.
+
+ To compile this driver as a module, choose M here. The module
+ will be called pxa168_eth.
+
config NET_NETX
tristate "NetX Ethernet support"
select MII
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 0a0512a..a42d437 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -244,6 +244,7 @@ obj-$(CONFIG_MYRI10GE) += myri10ge/
obj-$(CONFIG_SMC91X) += smc91x.o
obj-$(CONFIG_SMC911X) += smc911x.o
obj-$(CONFIG_SMSC911X) += smsc911x.o
+obj-$(CONFIG_PXA168_ETH) += pxa168_eth.o
obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
obj-$(CONFIG_DM9000) += dm9000.o
obj-$(CONFIG_PASEMI_MAC) += pasemi_mac_driver.o
diff --git a/drivers/net/pxa168_eth.c b/drivers/net/pxa168_eth.c
new file mode 100644
index 0000000..f5a65c8
--- /dev/null
+++ b/drivers/net/pxa168_eth.c
@@ -0,0 +1,1569 @@
+/*
+ * PXA168 ethernet driver.
+ * Most of the code is derived from mv643xx ethernet driver.
+ *
+ * Copyright (C) 2010 Marvell International Ltd.
+ * Sachin Sanap <ssanap@marvell.com>
+ * Philip Rakity <prakity@marvell.com>
+ * Mark Brown <markb@marvell.com>
+ *
+ * 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 more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include <linux/init.h>
+#include <linux/dma-mapping.h>
+#include <linux/in.h>
+#include <linux/ip.h>
+#include <linux/tcp.h>
+#include <linux/udp.h>
+#include <linux/etherdevice.h>
+#include <linux/bitops.h>
+#include <linux/delay.h>
+#include <linux/ethtool.h>
+#include <linux/platform_device.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/workqueue.h>
+#include <linux/clk.h>
+#include <linux/phy.h>
+#include <linux/io.h>
+#include <linux/types.h>
+#include <asm/pgtable.h>
+#include <asm/system.h>
+#include <linux/delay.h>
+#include <linux/dma-mapping.h>
+#include <asm/cacheflush.h>
+#include <linux/pxa168_eth.h>
+
+#define DRIVER_NAME "pxa168-eth"
+#define DRIVER_VERSION "0.3"
+
+/*
+ * Registers
+ */
+
+#define PHY_ADDRESS 0x0000
+#define SMI 0x0010
+#define PORT_CONFIG 0x0400
+#define PORT_CONFIG_EXT 0x0408
+#define PORT_COMMAND 0x0410
+#define PORT_STATUS 0x0418
+#define HTPR 0x0428
+#define SDMA_CONFIG 0x0440
+#define SDMA_CMD 0x0448
+#define INT_CAUSE 0x0450
+#define INT_W_CLEAR 0x0454
+#define INT_MASK 0x0458
+#define ETH_F_RX_DESC_0 0x0480
+#define ETH_C_RX_DESC_0 0x04A0
+#define ETH_C_TX_DESC_1 0x04E4
+
+/* smi register */
+#define SMI_BUSY (1 << 28) /* 0 - Write, 1 - Read */
+#define SMI_R_VALID (1 << 27) /* 0 - Write, 1 - Read */
+#define SMI_OP_W (0 << 26) /* Write operation */
+#define SMI_OP_R (1 << 26) /* Read operation */
+
+#define PHY_WAIT_ITERATIONS 500
+
+#define PXA168_ETH_PHY_ADDR_DEFAULT 0
+/* RX & TX descriptor command */
+#define BUF_OWNED_BY_DMA (1 << 31)
+
+/* RX descriptor status */
+#define RX_EN_INT (1 << 23)
+#define RX_FIRST_DESC (1 << 17)
+#define RX_LAST_DESC (1 << 16)
+#define RX_ERROR (1 << 15)
+
+/* TX descriptor command */
+#define TX_EN_INT (1 << 23)
+#define TX_GEN_CRC (1 << 22)
+#define TX_ZERO_PADDING (1 << 18)
+#define TX_FIRST_DESC (1 << 17)
+#define TX_LAST_DESC (1 << 16)
+#define TX_ERROR (1 << 15)
+
+/* SDMA_CMD */
+#define SDMA_CMD_AT (1 << 31)
+#define SDMA_CMD_TXDL (1 << 24)
+#define SDMA_CMD_TXDH (1 << 23)
+#define SDMA_CMD_AR (1 << 15)
+#define SDMA_CMD_ERD (1 << 7)
+
+/* Bit definitions of the Port Config Reg */
+#define PCR_HS (1 << 12)
+#define PCR_EN (1 << 7)
+#define PCR_PM (1 << 0)
+
+/* Bit definitions of the Port Config Extend Reg */
+#define PCXR_2BSM (1 << 28)
+#define PCXR_DSCP_EN (1 << 21)
+#define PCXR_MFL_1518 (0 << 14)
+#define PCXR_MFL_1536 (1 << 14)
+#define PCXR_MFL_2048 (2 << 14)
+#define PCXR_MFL_64K (3 << 14)
+#define PCXR_FLP (1 << 11)
+#define PCXR_PRIO_TX_OFF 3
+#define PCXR_TX_HIGH_PRI (7 << PCXR_PRIO_TX_OFF)
+
+/* Bit definitions of the SDMA Config Reg */
+#define SDCR_BSZ_OFF 12
+#define SDCR_BSZ8 (3 << SDCR_BSZ_OFF)
+#define SDCR_BSZ4 (2 << SDCR_BSZ_OFF)
+#define SDCR_BSZ2 (1 << SDCR_BSZ_OFF)
+#define SDCR_BSZ1 (0 << SDCR_BSZ_OFF)
+#define SDCR_BLMR (1 << 6)
+#define SDCR_BLMT (1 << 7)
+#define SDCR_RIFB (1 << 9)
+#define SDCR_RC_OFF 2
+#define SDCR_RC_MAX_RETRANS (0xf << SDCR_RC_OFF)
+
+/*
+ * Bit definitions of the Interrupt Cause Reg
+ * and Interrupt MASK Reg is the same
+ */
+#define ICR_RXBUF (1 << 0)
+#define ICR_TXBUF_H (1 << 2)
+#define ICR_TXBUF_L (1 << 3)
+#define ICR_TXEND_H (1 << 6)
+#define ICR_TXEND_L (1 << 7)
+#define ICR_RXERR (1 << 8)
+#define ICR_TXERR_H (1 << 10)
+#define ICR_TXERR_L (1 << 11)
+#define ICR_TX_UDR (1 << 13)
+#define ICR_MII_CH (1 << 28)
+
+#define ALL_INTS (ICR_TXBUF_H | ICR_TXBUF_L | ICR_TX_UDR |\
+ ICR_TXERR_H | ICR_TXERR_L |\
+ ICR_TXEND_H | ICR_TXEND_L |\
+ ICR_RXBUF | ICR_RXERR | ICR_MII_CH)
+
+#define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */
+#define ETH_DATA_LEN 1500
+#define MAX_PKT_SIZE 1518
+
+#define NUM_RX_DESCS 64
+#define NUM_TX_DESCS 64
+#define MAX_DESCS_PER_HIGH (60)
+#define TX_DESC_COUNT_LOW (10)
+
+#define HASH_ADD 0
+#define HASH_DELETE 1
+#define HASH_ADDR_TABLE_SIZE 0x4000 /* 16K (1/2K address - PCR_HS == 1) */
+#define HOP_NUMBER 12
+
+/* Bit definitions for Port status */
+#define PORT_SPEED_100 (1 << 0)
+#define FULL_DUPLEX (1 << 1)
+#define FLOW_CONTROL_ENABLED (1 << 2)
+#define LINK_UP (1 << 3)
+
+/* Bit definitions for work to be done */
+#define WORK_LINK (1 << 0)
+#define WORK_TX_DONE (1 << 1)
+
+struct rx_desc {
+ u32 cmd_sts; /* Descriptor command status */
+ u16 byte_cnt; /* Descriptor buffer byte count */
+ u16 buf_size; /* Buffer size */
+ u32 buf_ptr; /* Descriptor buffer pointer */
+ u32 next_desc_ptr; /* Next descriptor pointer */
+};
+
+struct tx_desc {
+ u32 cmd_sts; /* Command/status field */
+ u16 reserved;
+ u16 byte_cnt; /* buffer byte count */
+ u32 buf_ptr; /* pointer to buffer for this descriptor */
+ u32 next_desc_ptr; /* Pointer to next descriptor */
+};
+
+struct pxa168_eth_private {
+ int rx_resource_err; /* Rx ring resource error flag */
+
+ /* Next available and first returning Rx resource */
+ int rx_curr_desc_q, rx_used_desc_q;
+
+ /* Next available and first returning Tx resource */
+ int tx_curr_desc_q, tx_used_desc_q;
+
+ struct rx_desc *p_rx_desc_area;
+ dma_addr_t rx_desc_dma;
+ int rx_desc_area_size;
+ struct sk_buff **rx_skb;
+
+ struct tx_desc *p_tx_desc_area;
+ dma_addr_t tx_desc_dma;
+ int tx_desc_area_size;
+ struct sk_buff **tx_skb;
+
+ struct work_struct tx_timeout_task;
+
+ struct net_device *dev;
+ struct napi_struct napi;
+ u8 work_todo;
+
+ struct net_device_stats stats;
+ /* Size of Tx Ring per queue */
+ int tx_ring_size;
+ /* Number of tx descriptors in use */
+ int tx_desc_count;
+ /* Size of Rx Ring per queue */
+ int rx_ring_size;
+ /* Number of rx descriptors in use */
+ int rx_desc_count;
+
+ /*
+ * Used in case RX Ring is empty, which can occur when
+ * system does not have resources (skb's)
+ */
+ struct timer_list timeout;
+ struct mii_bus *smi_bus;
+ struct phy_device *phy;
+
+ /* clock */
+ struct clk *clk;
+ struct pxa168_eth_platform_data *pd;
+ /*
+ * Ethernet controller base address.
+ */
+ void __iomem *base;
+
+ /* Pointer to the hardware address filter table */
+ void *htpr;
+ dma_addr_t htpr_dma;
+};
+
+struct addr_table_entry {
+ __le32 lo;
+ __le32 hi;
+};
+
+/* Bit fields of a Hash Table Entry */
+enum hash_table_entry {
+ HASH_ENTRY_VALID = 1,
+ SKIP = 2,
+ HASH_ENTRY_RECEIVE_DISCARD = 4,
+ HASH_ENTRY_RECEIVE_DISCARD_BIT = 2
+};
+
+static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+static int pxa168_set_settings(struct net_device *dev, struct ethtool_cmd *cmd);
+static int pxa168_init_hw(struct pxa168_eth_private *pep);
+static void eth_port_reset(struct net_device *dev);
+static void eth_port_start(struct net_device *dev);
+static int pxa168_eth_open(struct net_device *dev);
+static int pxa168_eth_stop(struct net_device *dev);
+static int ethernet_phy_setup(struct net_device *dev);
+
+static inline u32 rdl(struct pxa168_eth_private *pep, int offset)
+{
+ return readl(pep->base + offset);
+}
+
+static inline void wrl(struct pxa168_eth_private *pep, int offset, u32 data)
+{
+ writel(data, pep->base + offset);
+}
+
+static void abort_dma(struct pxa168_eth_private *pep)
+{
+ int delay;
+ int max_retries = 40;
+
+ do {
+ wrl(pep, SDMA_CMD, SDMA_CMD_AR | SDMA_CMD_AT);
+ udelay(100);
+
+ delay = 10;
+ while ((rdl(pep, SDMA_CMD) & (SDMA_CMD_AR | SDMA_CMD_AT))
+ && delay-- > 0) {
+ udelay(10);
+ }
+ } while (max_retries-- > 0 && delay <= 0);
+
+ if (max_retries <= 0)
+ printk(KERN_ERR "%s : DMA Stuck\n", __func__);
+}
+
+static int ethernet_phy_get(struct pxa168_eth_private *pep)
+{
+ unsigned int reg_data;
+
+ reg_data = rdl(pep, PHY_ADDRESS);
+
+ return reg_data & 0x1f;
+}
+
+static void ethernet_phy_set_addr(struct pxa168_eth_private *pep, int phy_addr)
+{
+ u32 reg_data;
+
+ reg_data = rdl(pep, PHY_ADDRESS);
+ reg_data &= ~(0x1f);
+ reg_data |= phy_addr & 0x1f;
+ wrl(pep, PHY_ADDRESS, reg_data);
+}
+
+static void ethernet_phy_reset(struct pxa168_eth_private *pep)
+{
+ int data;
+
+ data = phy_read(pep->phy, MII_BMCR);
+ if (data < 0)
+ return;
+
+ data |= BMCR_RESET;
+ if (phy_write(pep->phy, MII_BMCR, data) < 0)
+ return;
+
+ do {
+ data = phy_read(pep->phy, MII_BMCR);
+ } while (data >= 0 && data & BMCR_RESET);
+}
+
+static void rxq_refill(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ struct sk_buff *skb;
+ struct rx_desc *p_used_rx_desc;
+ int used_rx_desc;
+
+ while (pep->rx_desc_count < pep->rx_ring_size) {
+ skb = dev_alloc_skb(MAX_PKT_SIZE + ETH_HW_IP_ALIGN);
+ if (!skb)
+ break;
+ pep->rx_desc_count++;
+ /* Get 'used' Rx descriptor */
+ used_rx_desc = pep->rx_used_desc_q;
+ p_used_rx_desc = &pep->p_rx_desc_area[used_rx_desc];
+ p_used_rx_desc->buf_ptr = dma_map_single(NULL,
+ skb->data,
+ MAX_PKT_SIZE +
+ ETH_HW_IP_ALIGN,
+ DMA_FROM_DEVICE);
+ p_used_rx_desc->buf_size = MAX_PKT_SIZE + ETH_HW_IP_ALIGN;
+ pep->rx_skb[used_rx_desc] = skb;
+
+ /* Return the descriptor to DMA ownership */
+ wmb();
+ p_used_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT;
+ wmb();
+
+ /* Move the used descriptor pointer to the next descriptor */
+ pep->rx_used_desc_q = (used_rx_desc + 1) % pep->rx_ring_size;
+
+ /* Any Rx return cancels the Rx resource error status */
+ pep->rx_resource_err = 0;
+
+ skb_reserve(skb, ETH_HW_IP_ALIGN);
+ }
+
+ /*
+ * If RX ring is empty of SKB, set a timer to try allocating
+ * again at a later time.
+ */
+ if (pep->rx_desc_count == 0) {
+ pep->timeout.expires = jiffies + (HZ / 10);
+ add_timer(&pep->timeout);
+ }
+}
+
+static inline void rxq_refill_timer_wrapper(unsigned long data)
+{
+ struct pxa168_eth_private *pep = (void *)data;
+ napi_schedule(&pep->napi);
+}
+
+static inline u8 flip_8_bits(u8 x)
+{
+ return (((x) & 0x01) << 3) | (((x) & 0x002) << 1)
+ | (((x) & 0x04) >> 1) | (((x) & 0x008) >> 3)
+ | (((x) & 0x10) << 3) | (((x) & 0x20) << 1)
+ | (((x) & 0x40) >> 1) | (((x) & 0x80) >> 3);
+}
+
+static void nibble_swap_every_byte(unsigned char *mac_addr)
+{
+ int i;
+ for (i = 0; i < ETH_ALEN; i++) {
+ mac_addr[i] = ((mac_addr[i] & 0x0f) << 4) |
+ ((mac_addr[i] & 0xf0) >> 4);
+ }
+}
+
+static void inverse_every_nibble(unsigned char *mac_addr)
+{
+ int i;
+ for (i = 0; i < ETH_ALEN; i++)
+ mac_addr[i] = flip_8_bits(mac_addr[i]);
+}
+
+/*
+ * ----------------------------------------------------------------------------
+ * This function will calculate the hash function of the address.
+ * Inputs
+ * mac_addr_orig - MAC address.
+ * Outputs
+ * return the calculated entry.
+ */
+static u32 hash_function(unsigned char *mac_addr_orig)
+{
+ u32 hash_result;
+ u32 addr0;
+ u32 addr1;
+ u32 addr2;
+ u32 addr3;
+ unsigned char mac_addr[ETH_ALEN];
+
+ /* Make a copy of MAC address since we are going to performe bit
+ * operations on it
+ */
+ memcpy(mac_addr, mac_addr_orig, ETH_ALEN);
+
+ nibble_swap_every_byte(mac_addr);
+ inverse_every_nibble(mac_addr);
+
+ addr0 = (mac_addr[5] >> 2) & 0x03f;
+ addr1 = (mac_addr[5] & 0x003) | (((mac_addr[4] & 0x7f)) << 2);
+ addr2 = ((mac_addr[4] & 0x80) >> 7) | mac_addr[3] << 1;
+ addr3 = (mac_addr[2] & 0x0ff) | ((mac_addr[1] & 1) << 8);
+
+ hash_result = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);
+ hash_result = hash_result & 0x07ff;
+ return hash_result;
+}
+
+/*
+ * ----------------------------------------------------------------------------
+ * This function will add/del an entry to the address table.
+ * Inputs
+ * pep - ETHERNET .
+ * mac_addr - MAC address.
+ * skip - if 1, skip this address.Used in case of deleting an entry which is a
+ * part of chain in the hash table.We cant just delete the entry since
+ * that will break the chain.We need to defragment the tables time to
+ * time.
+ * rd - 0 Discard packet upon match.
+ * - 1 Receive packet upon match.
+ * Outputs
+ * address table entry is added/deleted.
+ * 0 if success.
+ * -ENOSPC if table full
+ */
+static int add_del_hash_entry(struct pxa168_eth_private *pep,
+ unsigned char *mac_addr,
+ u32 rd, u32 skip, int del)
+{
+ struct addr_table_entry *entry, *start;
+ u32 new_high;
+ u32 new_low;
+ u32 i;
+
+ new_low = (((mac_addr[1] >> 4) & 0xf) << 15)
+ | (((mac_addr[1] >> 0) & 0xf) << 11)
+ | (((mac_addr[0] >> 4) & 0xf) << 7)
+ | (((mac_addr[0] >> 0) & 0xf) << 3)
+ | (((mac_addr[3] >> 4) & 0x1) << 31)
+ | (((mac_addr[3] >> 0) & 0xf) << 27)
+ | (((mac_addr[2] >> 4) & 0xf) << 23)
+ | (((mac_addr[2] >> 0) & 0xf) << 19)
+ | (skip << SKIP) | (rd << HASH_ENTRY_RECEIVE_DISCARD_BIT)
+ | HASH_ENTRY_VALID;
+
+ new_high = (((mac_addr[5] >> 4) & 0xf) << 15)
+ | (((mac_addr[5] >> 0) & 0xf) << 11)
+ | (((mac_addr[4] >> 4) & 0xf) << 7)
+ | (((mac_addr[4] >> 0) & 0xf) << 3)
+ | (((mac_addr[3] >> 5) & 0x7) << 0);
+
+ /*
+ * Pick the appropriate table, start scanning for free/reusable
+ * entries at the index obtained by hashing the specified MAC address
+ */
+ start = (struct addr_table_entry *)(pep->htpr);
+ entry = start + hash_function(mac_addr);
+ for (i = 0; i < HOP_NUMBER; i++) {
+ if (!(le32_to_cpu(entry->lo) & HASH_ENTRY_VALID)) {
+ break;
+ } else {
+ /* if same address put in same position */
+ if (((le32_to_cpu(entry->lo) & 0xfffffff8) ==
+ (new_low & 0xfffffff8)) &&
+ (le32_to_cpu(entry->hi) == new_high)) {
+ break;
+ }
+ }
+ if (entry == start + 0x7ff)
+ entry = start;
+ else
+ entry++;
+ }
+
+ if (((le32_to_cpu(entry->lo) & 0xfffffff8) != (new_low & 0xfffffff8)) &&
+ (le32_to_cpu(entry->hi) != new_high) && del)
+ return 0;
+
+ if (i == HOP_NUMBER) {
+ if (!del) {
+ printk(KERN_INFO "%s: table section is full\n",
+ __FILE__);
+ return -ENOSPC;
+ } else
+ return 0;
+ }
+
+ /*
+ * Update the selected entry
+ */
+ if (del) {
+ entry->hi = 0;
+ entry->lo = 0;
+ } else {
+ entry->hi = cpu_to_le32(new_high);
+ entry->lo = cpu_to_le32(new_low);
+ }
+
+ return 0;
+}
+
+/*
+ * ----------------------------------------------------------------------------
+ * Create an addressTable entry from MAC address info
+ * found in the specifed net_device struct
+ *
+ * Input : pointer to ethernet interface network device structure
+ * Output : N/A
+ */
+static void update_hash_table_mac_address(struct pxa168_eth_private *pep,
+ unsigned char *oaddr,
+ unsigned char *addr)
+{
+ /* Delete old entry */
+ if (oaddr)
+ add_del_hash_entry(pep, oaddr, 1, 0, HASH_DELETE);
+ /* Add new entry */
+ add_del_hash_entry(pep, addr, 1, 0, HASH_ADD);
+}
+
+static int init_hash_table(struct pxa168_eth_private *pep)
+{
+ /*
+ * Hardware expects CPU to build a hash table based on a predefined
+ * hash function and populate it based on hardware address. The
+ * location of the hash table is identified by 32-bit pointer stored
+ * in HTPR internal register. Two possible sizes exists for the hash
+ * table 8kB (256kB of DRAM required (4 x 64 kB banks)) and 1/2kB
+ * (16kB of DRAM required (4 x 4 kB banks)).We currently only support
+ * 1/2kB.
+ */
+ /* TODO: Add support for 8kB hash table and alternative hash
+ * function.Driver can dynamically switch to them if the 1/2kB hash
+ * table is full.
+ */
+ if (pep->htpr == NULL) {
+ pep->htpr = dma_alloc_coherent(NULL,
+ HASH_ADDR_TABLE_SIZE,
+ &pep->htpr_dma, GFP_KERNEL);
+ if (pep->htpr == NULL)
+ return -ENOMEM;
+ }
+ memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE);
+ wrl(pep, HTPR, pep->htpr_dma);
+ return 0;
+}
+
+static void pxa168_eth_set_rx_mode(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ struct netdev_hw_addr *ha;
+ u32 val;
+
+ val = rdl(pep, PORT_CONFIG);
+ if (dev->flags & IFF_PROMISC)
+ val |= PCR_PM;
+ else
+ val &= ~PCR_PM;
+ wrl(pep, PORT_CONFIG, val);
+ netdev_for_each_mc_addr(ha, dev)
+ update_hash_table_mac_address(pep, NULL, ha->addr);
+}
+
+static int pxa168_eth_set_mac_address(struct net_device *dev, void *addr)
+{
+ struct sockaddr *sa = addr;
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ unsigned char oldMac[ETH_ALEN];
+
+ if (!is_valid_ether_addr(sa->sa_data))
+ return -EINVAL;
+ memcpy(oldMac, dev->dev_addr, ETH_ALEN);
+ memcpy(dev->dev_addr, sa->sa_data, ETH_ALEN);
+ netif_addr_lock_bh(dev);
+ update_hash_table_mac_address(pep, oldMac, dev->dev_addr);
+ netif_addr_unlock_bh(dev);
+ return 0;
+}
+
+static void eth_port_start(struct net_device *dev)
+{
+ unsigned int val = 0;
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ int tx_curr_desc, rx_curr_desc;
+
+ /* Perform PHY reset, if there is a PHY. */
+ if (pep->phy != NULL) {
+ struct ethtool_cmd cmd;
+
+ pxa168_get_settings(pep->dev, &cmd);
+ ethernet_phy_reset(pep);
+ pxa168_set_settings(pep->dev, &cmd);
+ }
+
+ /* Assignment of Tx CTRP of given queue */
+ tx_curr_desc = pep->tx_curr_desc_q;
+ wrl(pep, ETH_C_TX_DESC_1,
+ (u32) ((struct tx_desc *)pep->tx_desc_dma + tx_curr_desc));
+
+ /* Assignment of Rx CRDP of given queue */
+ rx_curr_desc = pep->rx_curr_desc_q;
+ wrl(pep, ETH_C_RX_DESC_0,
+ (u32) ((struct rx_desc *)pep->rx_desc_dma + rx_curr_desc));
+
+ wrl(pep, ETH_F_RX_DESC_0,
+ (u32) ((struct rx_desc *)pep->rx_desc_dma + rx_curr_desc));
+
+ /* Clear all interrupts */
+ wrl(pep, INT_CAUSE, 0);
+
+ /* Enable all interrupts for receive, transmit and error. */
+ wrl(pep, INT_MASK, ALL_INTS);
+
+ val = rdl(pep, PORT_CONFIG);
+ val |= PCR_EN;
+ wrl(pep, PORT_CONFIG, val);
+
+ /* Start RX DMA engine */
+ val = rdl(pep, SDMA_CMD);
+ val |= SDMA_CMD_ERD;
+ wrl(pep, SDMA_CMD, val);
+}
+
+static void eth_port_reset(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ unsigned int val = 0;
+
+ /* Stop all interrupts for receive, transmit and error. */
+ wrl(pep, INT_MASK, 0);
+
+ /* Clear all interrupts */
+ wrl(pep, INT_CAUSE, 0);
+
+ /* Stop RX DMA */
+ val = rdl(pep, SDMA_CMD);
+ val &= ~SDMA_CMD_ERD; /* abort dma command */
+
+ /* Abort any transmit and receive operations and put DMA
+ * in idle state.
+ */
+ abort_dma(pep);
+
+ /* Disable port */
+ val = rdl(pep, PORT_CONFIG);
+ val &= ~PCR_EN;
+ wrl(pep, PORT_CONFIG, val);
+}
+
+/*
+ * txq_reclaim - Free the tx desc data for completed descriptors
+ * If force is non-zero, frees uncompleted descriptors as well
+ */
+static int txq_reclaim(struct net_device *dev, int force)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ struct tx_desc *desc;
+ u32 cmd_sts;
+ struct sk_buff *skb;
+ int tx_index;
+ dma_addr_t addr;
+ int count;
+ int released = 0;
+
+ netif_tx_lock(dev);
+
+ pep->work_todo &= ~(WORK_TX_DONE);
+ while (pep->tx_desc_count > 0) {
+ tx_index = pep->tx_used_desc_q;
+ desc = &pep->p_tx_desc_area[tx_index];
+ cmd_sts = desc->cmd_sts;
+ if (!force && (cmd_sts & BUF_OWNED_BY_DMA)) {
+ if (released > 0) {
+ goto txq_reclaim_end;
+ } else {
+ released = -1;
+ goto txq_reclaim_end;
+ }
+ }
+ pep->tx_used_desc_q = (tx_index + 1) % pep->tx_ring_size;
+ pep->tx_desc_count--;
+ addr = desc->buf_ptr;
+ count = desc->byte_cnt;
+ skb = pep->tx_skb[tx_index];
+ if (skb)
+ pep->tx_skb[tx_index] = NULL;
+
+ if (cmd_sts & TX_ERROR) {
+ if (net_ratelimit())
+ printk(KERN_ERR "%s: Error in TX\n", dev->name);
+ dev->stats.tx_errors++;
+ }
+ dma_unmap_single(NULL, addr, count, DMA_TO_DEVICE);
+ if (skb)
+ dev_kfree_skb_irq(skb);
+ released++;
+ }
+txq_reclaim_end:
+ netif_tx_unlock(dev);
+ return released;
+}
+
+static void pxa168_eth_tx_timeout(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+
+ printk(KERN_INFO "%s: TX timeout desc_count %d\n",
+ dev->name, pep->tx_desc_count);
+
+ schedule_work(&pep->tx_timeout_task);
+}
+
+static void pxa168_eth_tx_timeout_task(struct work_struct *work)
+{
+ struct pxa168_eth_private *pep = container_of(work,
+ struct pxa168_eth_private,
+ tx_timeout_task);
+ struct net_device *dev = pep->dev;
+ pxa168_eth_stop(dev);
+ pxa168_eth_open(dev);
+}
+
+static int rxq_process(struct net_device *dev, int budget)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+ unsigned int received_packets = 0;
+ struct sk_buff *skb;
+
+ while (budget-- > 0) {
+
+ int rx_next_curr_desc, rx_curr_desc, rx_used_desc;
+ struct rx_desc *rx_desc;
+ unsigned int cmd_sts;
+
+ /* Do not process Rx ring in case of Rx ring resource error */
+ if (pep->rx_resource_err)
+ break;
+ rx_curr_desc = pep->rx_curr_desc_q;
+ rx_used_desc = pep->rx_used_desc_q;
+ rx_desc = &pep->p_rx_desc_area[rx_curr_desc];
+ cmd_sts = rx_desc->cmd_sts;
+ rmb();
+ if (cmd_sts & (BUF_OWNED_BY_DMA))
+ break;
+ skb = pep->rx_skb[rx_curr_desc];
+ pep->rx_skb[rx_curr_desc] = NULL;
+
+ rx_next_curr_desc = (rx_curr_desc + 1) % pep->rx_ring_size;
+ pep->rx_curr_desc_q = rx_next_curr_desc;
+
+ /* Rx descriptors exhausted. */
+ /* Set the Rx ring resource error flag */
+ if (rx_next_curr_desc == rx_used_desc)
+ pep->rx_resource_err = 1;
+ pep->rx_desc_count--;
+ dma_unmap_single(NULL, rx_desc->buf_ptr,
+ MAX_PKT_SIZE + ETH_HW_IP_ALIGN,
+ DMA_FROM_DEVICE);
+ received_packets++;
+ /*
+ * Update statistics.
+ * Note byte count includes 4 byte CRC count
+ */
+ stats->rx_packets++;
+ stats->rx_bytes += rx_desc->byte_cnt;
+ /*
+ * In case received a packet without first / last bits on OR
+ * the error summary bit is on, the packets needs to be droped.
+ */
+ if (((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
+ (RX_FIRST_DESC | RX_LAST_DESC))
+ || (cmd_sts & RX_ERROR)) {
+
+ stats->rx_dropped++;
+ if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
+ (RX_FIRST_DESC | RX_LAST_DESC)) {
+ if (net_ratelimit())
+ printk(KERN_ERR
+ "%s: Rx pkt on multiple desc\n",
+ dev->name);
+ }
+ if (cmd_sts & RX_ERROR)
+ stats->rx_errors++;
+ dev_kfree_skb_irq(skb);
+ } else {
+ /*
+ * The -4 is for the CRC in the trailer of the
+ * received packet
+ */
+ skb_put(skb, rx_desc->byte_cnt - 4);
+ skb->protocol = eth_type_trans(skb, dev);
+ netif_receive_skb(skb);
+ }
+ dev->last_rx = jiffies;
+ }
+ /* Fill RX ring with skb's */
+ rxq_refill(dev);
+ return received_packets;
+}
+
+static int pxa168_eth_collect_events(struct pxa168_eth_private *pep,
+ struct net_device *dev)
+{
+ u32 icr;
+ int ret = 0;
+
+ icr = rdl(pep, INT_CAUSE);
+ if (0x00 == icr)
+ return IRQ_NONE;
+
+ wrl(pep, INT_CAUSE, icr ^ 0xffffffff);
+ if (icr & (ICR_TXBUF_H | ICR_TXBUF_L)) {
+ pep->work_todo |= WORK_TX_DONE;
+ ret = 1;
+ }
+ if (icr & ICR_RXBUF)
+ ret = 1;
+ if (icr & ICR_MII_CH) {
+ pep->work_todo |= WORK_LINK;
+ ret = 1;
+ }
+ return ret;
+}
+
+static void handle_link_event(struct pxa168_eth_private *pep)
+{
+ struct net_device *dev = pep->dev;
+ u32 port_status;
+ int speed;
+ int duplex;
+ int fc;
+
+ port_status = rdl(pep, PORT_STATUS);
+ if (!(port_status & LINK_UP)) {
+ if (netif_carrier_ok(dev)) {
+ printk(KERN_INFO "%s: link down\n", dev->name);
+ netif_carrier_off(dev);
+ txq_reclaim(dev, 1);
+ }
+ return;
+ }
+ if (port_status & PORT_SPEED_100)
+ speed = 100;
+ else
+ speed = 10;
+
+ duplex = (port_status & FULL_DUPLEX) ? 1 : 0;
+ fc = (port_status & FLOW_CONTROL_ENABLED) ? 1 : 0;
+ printk(KERN_INFO "%s: link up, %d Mb/s, %s duplex, "
+ "flow control %sabled\n", dev->name,
+ speed, duplex ? "full" : "half", fc ? "en" : "dis");
+ if (!netif_carrier_ok(dev))
+ netif_carrier_on(dev);
+}
+
+static irqreturn_t pxa168_eth_int_handler(int irq, void *dev_id)
+{
+ struct net_device *dev = (struct net_device *)dev_id;
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+
+ if (unlikely(!pxa168_eth_collect_events(pep, dev)))
+ return IRQ_NONE;
+ /* Disable interrupts */
+ wrl(pep, INT_MASK, 0);
+ napi_schedule(&pep->napi);
+ return IRQ_HANDLED;
+}
+
+static int set_port_config_ext(struct pxa168_eth_private *pep, int mtu)
+{
+ int mtu_size;
+
+ if ((mtu > ETH_DATA_LEN) || (mtu < 64))
+ return -EINVAL;
+
+ mtu_size = PCXR_MFL_1518;
+ /* Extended Port Configuration */
+ wrl(pep,
+ PORT_CONFIG_EXT, PCXR_2BSM | /* Two byte suffix aligns IP hdr */
+ PCXR_DSCP_EN | /* Enable DSCP in IP */
+ mtu_size | PCXR_FLP | /* do not force link pass */
+ PCXR_TX_HIGH_PRI); /* Transmit - high priority queue */
+
+ (pep->dev)->mtu = mtu;
+ return 0;
+}
+
+static int pxa168_init_hw(struct pxa168_eth_private *pep)
+{
+ int err = 0;
+
+ /* Disable interrupts */
+ wrl(pep, INT_MASK, 0);
+ wrl(pep, INT_CAUSE, 0);
+ /* Write to ICR to clear interrupts. */
+ wrl(pep, INT_W_CLEAR, 0);
+ /* Abort any transmit and receive operations and put DMA
+ * in idle state.
+ */
+ abort_dma(pep);
+ /* Initialize address hash table */
+ err = init_hash_table(pep);
+ if (err)
+ return err;
+ /* SDMA configuration */
+ wrl(pep, SDMA_CONFIG, SDCR_BSZ8 | /* Burst size = 32 bytes */
+ SDCR_RIFB | /* Rx interrupt on frame */
+ SDCR_BLMT | /* Little endian transmit */
+ SDCR_BLMR | /* Little endian receive */
+ SDCR_RC_MAX_RETRANS); /* Max retransmit count */
+ /* Port Configuration */
+ wrl(pep, PORT_CONFIG, PCR_HS); /* Hash size is 1/2kb */
+ set_port_config_ext(pep, (pep->dev)->mtu);
+ return err;
+}
+
+static int rxq_init(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ struct rx_desc *p_rx_desc;
+ int size = 0, i = 0;
+ int rx_desc_num = pep->rx_ring_size;
+
+ /* Allocate RX skb rings */
+ pep->rx_skb = kmalloc(sizeof(*pep->rx_skb) * pep->rx_ring_size,
+ GFP_KERNEL);
+ if (!pep->rx_skb) {
+ printk(KERN_ERR "%s: Cannot alloc RX skb ring\n", dev->name);
+ return -ENOMEM;
+ }
+ /* Allocate RX ring */
+ pep->rx_desc_count = 0;
+ size = pep->rx_ring_size * sizeof(struct rx_desc);
+ pep->rx_desc_area_size = size;
+ pep->p_rx_desc_area = dma_alloc_coherent(NULL, size,
+ &pep->rx_desc_dma, GFP_KERNEL);
+ if (!pep->p_rx_desc_area) {
+ printk(KERN_ERR "%s: Cannot alloc RX ring (size %d bytes)\n",
+ dev->name, size);
+ goto out;
+ }
+ memset((void *)pep->p_rx_desc_area, 0, size);
+ /* initialize the next_desc_ptr links in the Rx descriptors ring */
+ p_rx_desc = (struct rx_desc *)pep->p_rx_desc_area;
+ for (i = 0; i < rx_desc_num; i++) {
+ p_rx_desc[i].next_desc_ptr = pep->rx_desc_dma +
+ ((i + 1) % rx_desc_num) * sizeof(struct rx_desc);
+ }
+ /* Save Rx desc pointer to driver struct. */
+ pep->rx_curr_desc_q = 0;
+ pep->rx_used_desc_q = 0;
+ pep->rx_desc_area_size = rx_desc_num * sizeof(struct rx_desc);
+ return 0;
+out:
+ kfree(pep->rx_skb);
+ return -ENOMEM;
+}
+
+static void rxq_deinit(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ int curr;
+
+ /* Free preallocated skb's on RX rings */
+ for (curr = 0; pep->rx_desc_count && curr < pep->rx_ring_size; curr++) {
+ if (pep->rx_skb[curr]) {
+ dev_kfree_skb(pep->rx_skb[curr]);
+ pep->rx_desc_count--;
+ }
+ }
+ if (pep->rx_desc_count)
+ printk(KERN_ERR
+ "Error in freeing Rx Ring. %d skb's still\n",
+ pep->rx_desc_count);
+ /* Free RX ring */
+ if (pep->p_rx_desc_area)
+ dma_free_coherent(NULL, pep->rx_desc_area_size,
+ pep->p_rx_desc_area, pep->rx_desc_dma);
+ kfree(pep->rx_skb);
+}
+
+static int txq_init(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ struct tx_desc *p_tx_desc;
+ int size = 0, i = 0;
+ int tx_desc_num = pep->tx_ring_size;
+
+ pep->tx_skb = kmalloc(sizeof(*pep->tx_skb) * pep->tx_ring_size,
+ GFP_KERNEL);
+ if (!pep->tx_skb) {
+ printk(KERN_ERR "%s: Cannot alloc TX skb ring\n", dev->name);
+ return -ENOMEM;
+ }
+ /* Allocate TX ring */
+ pep->tx_desc_count = 0;
+ size = pep->tx_ring_size * sizeof(struct tx_desc);
+ pep->tx_desc_area_size = size;
+ pep->p_tx_desc_area = dma_alloc_coherent(NULL, size,
+ &pep->tx_desc_dma, GFP_KERNEL);
+ if (!pep->p_tx_desc_area) {
+ printk(KERN_ERR "%s: Cannot allocate Tx Ring (size %d bytes)\n",
+ dev->name, size);
+ goto out;
+ }
+ memset((void *)pep->p_tx_desc_area, 0, pep->tx_desc_area_size);
+ /* Initialize the next_desc_ptr links in the Tx descriptors ring */
+ p_tx_desc = (struct tx_desc *)pep->p_tx_desc_area;
+ for (i = 0; i < tx_desc_num; i++) {
+ p_tx_desc[i].next_desc_ptr = pep->tx_desc_dma +
+ ((i + 1) % tx_desc_num) * sizeof(struct tx_desc);
+ }
+ pep->tx_curr_desc_q = 0;
+ pep->tx_used_desc_q = 0;
+ pep->tx_desc_area_size = tx_desc_num * sizeof(struct tx_desc);
+ return 0;
+out:
+ kfree(pep->tx_skb);
+ return -ENOMEM;
+}
+
+static void txq_deinit(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+
+ /* Free outstanding skb's on TX ring */
+ txq_reclaim(dev, 1);
+ BUG_ON(pep->tx_used_desc_q != pep->tx_curr_desc_q);
+ /* Free TX ring */
+ if (pep->p_tx_desc_area)
+ dma_free_coherent(NULL, pep->tx_desc_area_size,
+ pep->p_tx_desc_area, pep->tx_desc_dma);
+ kfree(pep->tx_skb);
+}
+
+static int pxa168_eth_open(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ int err;
+
+ err = request_irq(dev->irq, pxa168_eth_int_handler,
+ IRQF_DISABLED , dev->name, dev);
+ if (err) {
+ dev_printk(KERN_ERR, &dev->dev, "can't assign irq\n");
+ return -EAGAIN;
+ }
+ pep->rx_resource_err = 0;
+ err = rxq_init(dev);
+ if (err != 0)
+ goto out_free_irq;
+ err = txq_init(dev);
+ if (err != 0)
+ goto out_free_rx_skb;
+ pep->rx_used_desc_q = 0;
+ pep->rx_curr_desc_q = 0;
+
+ /* Fill RX ring with skb's */
+ rxq_refill(dev);
+ pep->rx_used_desc_q = 0;
+ pep->rx_curr_desc_q = 0;
+ netif_carrier_off(dev);
+ eth_port_start(dev);
+ napi_enable(&pep->napi);
+ return 0;
+out_free_rx_skb:
+ rxq_deinit(dev);
+out_free_irq:
+ free_irq(dev->irq, dev);
+ return err;
+}
+
+static int pxa168_eth_stop(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ eth_port_reset(dev);
+
+ /* Disable interrupts */
+ wrl(pep, INT_MASK, 0);
+ wrl(pep, INT_CAUSE, 0);
+ /* Write to ICR to clear interrupts. */
+ wrl(pep, INT_W_CLEAR, 0);
+ napi_disable(&pep->napi);
+ del_timer_sync(&pep->timeout);
+ netif_carrier_off(dev);
+ free_irq(dev->irq, dev);
+ rxq_deinit(dev);
+ txq_deinit(dev);
+ return 0;
+}
+
+static int eth_alloc_tx_desc_index(struct pxa168_eth_private *pep)
+{
+ int tx_desc_curr;
+
+ tx_desc_curr = pep->tx_curr_desc_q;
+ pep->tx_curr_desc_q = (tx_desc_curr + 1) % pep->tx_ring_size;
+ BUG_ON(pep->tx_curr_desc_q == pep->tx_used_desc_q);
+ pep->tx_desc_count++;
+ return tx_desc_curr;
+}
+
+static void eth_tx_submit_descs_for_skb(struct pxa168_eth_private *pep,
+ struct sk_buff *skb)
+{
+ int tx_index;
+ struct tx_desc *desc;
+ int length;
+
+ tx_index = eth_alloc_tx_desc_index(pep);
+ desc = &pep->p_tx_desc_area[tx_index];
+ length = skb->len;
+ pep->tx_skb[tx_index] = skb;
+ desc->byte_cnt = length;
+ desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
+ wmb();
+ desc->cmd_sts = BUF_OWNED_BY_DMA | TX_GEN_CRC | TX_FIRST_DESC |
+ TX_ZERO_PADDING | TX_LAST_DESC;
+ if (unlikely(!(pep->tx_desc_count % (pep->tx_ring_size / 4))))
+ desc->cmd_sts |= TX_EN_INT;
+ wmb();
+ wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD);
+}
+
+static int pxa168_rx_poll(struct napi_struct *napi, int budget)
+{
+ struct pxa168_eth_private *pep =
+ container_of(napi, struct pxa168_eth_private, napi);
+ struct net_device *dev = pep->dev;
+ int work_done = 0;
+
+ if (unlikely(pep->work_todo & WORK_LINK)) {
+ pep->work_todo &= ~(WORK_LINK);
+ handle_link_event(pep);
+ }
+ /*
+ * We call txq_reclaim every time since in NAPI interupts are disabled
+ * and due to this we miss the TX_DONE interrupt,which is not updated in
+ * interrupt status register.
+ */
+ txq_reclaim(dev, 0);
+ if (netif_queue_stopped(dev)
+ && pep->tx_ring_size - pep->tx_desc_count > 1) {
+ netif_wake_queue(dev);
+ }
+ work_done = rxq_process(dev, budget);
+ if (work_done < budget) {
+ napi_complete(napi);
+ wrl(pep, INT_MASK, ALL_INTS);
+ }
+ return work_done;
+}
+
+static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ struct net_device_stats *stats = &dev->stats;
+
+ eth_tx_submit_descs_for_skb(pep, skb);
+ stats->tx_bytes += skb->len;
+ stats->tx_packets++;
+ dev->trans_start = jiffies;
+ if (pep->tx_ring_size - pep->tx_desc_count <= 1) {
+ /* We handled the current skb, but now we are out of space.*/
+ netif_stop_queue(dev);
+ }
+ return NETDEV_TX_OK;
+}
+
+static int pxa168_smi_read(struct mii_bus *bus, int phy_addr, int regnum)
+{
+ int val;
+ struct pxa168_eth_private *pep = bus->priv;
+ int i = 0;
+
+ /* wait for the SMI register to become available */
+ for (i = 0; (val = rdl(pep, SMI)) & SMI_BUSY; i++) {
+ if (i == PHY_WAIT_ITERATIONS) {
+ printk(KERN_ERR
+ "pxa168 PHY timeout, val=0x%x\n", val);
+ return -ETIMEDOUT;
+ }
+ udelay(1);
+ }
+ wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) | SMI_OP_R);
+ /* now wait for the data to be valid */
+ for (i = 0; !((val = rdl(pep, SMI)) & SMI_R_VALID); i++) {
+ if (i == PHY_WAIT_ITERATIONS) {
+ printk(KERN_ERR
+ "pxa168 PHY RD timeout, val=0x%x\n", val);
+ return -ETIMEDOUT;
+ }
+ udelay(1);
+ }
+ return val & 0xffff;
+}
+
+static int pxa168_smi_write(struct mii_bus *bus, int phy_addr, int regnum,
+ u16 value)
+{
+ struct pxa168_eth_private *pep = bus->priv;
+ int i;
+
+ /* wait for the SMI register to become available */
+ for (i = 0; rdl(pep, SMI) & SMI_BUSY; i++) {
+ if (i == PHY_WAIT_ITERATIONS) {
+ printk(KERN_ERR "pxa168 PHY busy timeout.\n");
+ return -ETIMEDOUT;
+ }
+ udelay(1);
+ }
+ wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) |
+ SMI_OP_W | (value & 0xffff));
+
+ return 0;
+}
+
+static int pxa168_eth_do_ioctl(struct net_device *dev, struct ifreq *ifr,
+ int cmd)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ if (pep->phy != NULL)
+ return phy_mii_ioctl(pep->phy, if_mii(ifr), cmd);
+ return -EOPNOTSUPP;
+}
+
+static struct phy_device *phy_scan(struct pxa168_eth_private *pep, int phy_addr)
+{
+ struct mii_bus *bus = pep->smi_bus;
+ struct phy_device *phydev;
+ int start;
+ int num;
+ int i;
+
+ if (phy_addr == PXA168_ETH_PHY_ADDR_DEFAULT) {
+ /* Scan entire range */
+ start = ethernet_phy_get(pep);
+ num = 32;
+ } else {
+ /* Use phy addr specific to platform */
+ start = phy_addr & 0x1f;
+ num = 1;
+ }
+ phydev = NULL;
+ for (i = 0; i < num; i++) {
+ int addr = (start + i) & 0x1f;
+ if (bus->phy_map[addr] == NULL)
+ mdiobus_scan(bus, addr);
+
+ if (phydev == NULL) {
+ phydev = bus->phy_map[addr];
+ if (phydev != NULL)
+ ethernet_phy_set_addr(pep, addr);
+ }
+ }
+
+ return phydev;
+}
+
+static void phy_init(struct pxa168_eth_private *pep, int speed, int duplex)
+{
+ struct phy_device *phy = pep->phy;
+ ethernet_phy_reset(pep);
+
+ phy_attach(pep->dev, dev_name(&phy->dev), 0, PHY_INTERFACE_MODE_MII);
+
+ if (speed == 0) {
+ phy->autoneg = AUTONEG_ENABLE;
+ phy->speed = 0;
+ phy->duplex = 0;
+ phy->supported &= PHY_BASIC_FEATURES;
+ phy->advertising = phy->supported | ADVERTISED_Autoneg;
+ } else {
+ phy->autoneg = AUTONEG_DISABLE;
+ phy->advertising = 0;
+ phy->speed = speed;
+ phy->duplex = duplex;
+ }
+ phy_start_aneg(phy);
+}
+
+static int ethernet_phy_setup(struct net_device *dev)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+
+ if (pep->pd != NULL) {
+ if (pep->pd->init)
+ pep->pd->init();
+ }
+ pep->phy = phy_scan(pep, pep->pd->phy_addr & 0x1f);
+ if (pep->phy != NULL)
+ phy_init(pep, pep->pd->speed, pep->pd->duplex);
+ update_hash_table_mac_address(pep, NULL, dev->dev_addr);
+ return 0;
+}
+
+static int get_random_mac_addr(struct net_device *dev)
+{
+ printk(KERN_INFO "%s:Using random mac address\n", dev->name);
+ random_ether_addr(dev->dev_addr);
+ return 0;
+}
+
+static int pxa168_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+ int err;
+
+ err = phy_read_status(pep->phy);
+ if (err == 0)
+ err = phy_ethtool_gset(pep->phy, cmd);
+ return err;
+}
+
+static int pxa168_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
+{
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+
+ return phy_ethtool_sset(pep->phy, cmd);
+}
+
+static void pxa168_get_drvinfo(struct net_device *dev,
+ struct ethtool_drvinfo *info)
+{
+ strncpy(info->driver, DRIVER_NAME, 32);
+ strncpy(info->version, DRIVER_VERSION, 32);
+ strncpy(info->fw_version, "N/A", 32);
+ strncpy(info->bus_info, "N/A", 32);
+}
+
+static u32 pxa168_get_link(struct net_device *dev)
+{
+ return !!netif_carrier_ok(dev);
+}
+
+static const struct ethtool_ops pxa168_ethtool_ops = {
+ .get_settings = pxa168_get_settings,
+ .set_settings = pxa168_set_settings,
+ .get_drvinfo = pxa168_get_drvinfo,
+ .get_link = pxa168_get_link,
+};
+
+static const struct net_device_ops pxa168_eth_netdev_ops = {
+ .ndo_open = pxa168_eth_open,
+ .ndo_stop = pxa168_eth_stop,
+ .ndo_start_xmit = pxa168_eth_start_xmit,
+ .ndo_set_rx_mode = pxa168_eth_set_rx_mode,
+ .ndo_set_mac_address = pxa168_eth_set_mac_address,
+ .ndo_validate_addr = eth_validate_addr,
+ .ndo_do_ioctl = pxa168_eth_do_ioctl,
+ .ndo_change_mtu = eth_change_mtu,
+ .ndo_tx_timeout = pxa168_eth_tx_timeout,
+};
+
+static int pxa168_eth_probe(struct platform_device *pdev)
+{
+ struct pxa168_eth_private *pep = NULL;
+ struct net_device *dev = NULL;
+ struct resource *res;
+ struct clk *clk;
+ int err;
+
+ printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
+
+ clk = clk_get(&pdev->dev, "MFUCLK");
+ if (IS_ERR(clk)) {
+ printk(KERN_ERR "fast Ethernet failed to get clock\n");
+ return -ENODEV;
+ }
+ clk_enable(clk);
+
+ dev = alloc_etherdev(sizeof(struct pxa168_eth_private));
+ if (!dev) {
+ err = -ENOMEM;
+ goto out;
+ }
+
+ platform_set_drvdata(pdev, dev);
+ pep = netdev_priv(dev);
+ pep->dev = dev;
+ pep->clk = clk;
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (res == NULL) {
+ err = -ENODEV;
+ goto out;
+ }
+ pep->base = ioremap(res->start, res->end - res->start + 1);
+ if (pep->base == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+ res = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
+ BUG_ON(!res);
+ dev->irq = res->start;
+ dev->netdev_ops = &pxa168_eth_netdev_ops;
+ dev->watchdog_timeo = 2 * HZ;
+ dev->base_addr = 0;
+ SET_ETHTOOL_OPS(dev, &pxa168_ethtool_ops);
+
+ INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
+
+ pep->rx_ring_size = NUM_RX_DESCS;
+ pep->tx_ring_size = NUM_TX_DESCS;
+ get_random_mac_addr(dev);
+ pep->pd = pdev->dev.platform_data;
+ netif_napi_add(dev, &pep->napi, pxa168_rx_poll, pep->rx_ring_size);
+
+ memset(&pep->timeout, 0, sizeof(struct timer_list));
+ init_timer(&pep->timeout);
+ pep->timeout.function = rxq_refill_timer_wrapper;
+ pep->timeout.data = (unsigned long)pep;
+
+ pep->smi_bus = mdiobus_alloc();
+ if (pep->smi_bus == NULL) {
+ err = -ENOMEM;
+ goto out;
+ }
+ pep->smi_bus->priv = pep;
+ pep->smi_bus->name = "pxa168_eth smi";
+ pep->smi_bus->read = pxa168_smi_read;
+ pep->smi_bus->write = pxa168_smi_write;
+ snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%d", pdev->id);
+ pep->smi_bus->parent = &pdev->dev;
+ pep->smi_bus->phy_mask = 0xffffffff;
+ if (mdiobus_register(pep->smi_bus) < 0) {
+ err = -ENOMEM;
+ goto out;
+ }
+ pxa168_init_hw(pep);
+ err = ethernet_phy_setup(dev);
+ if (err)
+ goto out;
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ err = register_netdev(dev);
+ if (err)
+ goto out;
+ return 0;
+out:
+ if (pep->clk) {
+ clk_disable(pep->clk);
+ clk_put(pep->clk);
+ pep->clk = NULL;
+ }
+ if (pep->base) {
+ iounmap(pep->base);
+ pep->base = NULL;
+ }
+ if (dev)
+ free_netdev(dev);
+ return err;
+}
+
+static int pxa168_eth_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct pxa168_eth_private *pep = netdev_priv(dev);
+
+ if (pep->htpr) {
+ dma_free_coherent(NULL, HASH_ADDR_TABLE_SIZE + 7,
+ pep->htpr, pep->htpr_dma);
+ pep->htpr = NULL;
+ }
+ if (pep->clk) {
+ clk_disable(pep->clk);
+ clk_put(pep->clk);
+ pep->clk = NULL;
+ }
+ if (pep->phy != NULL)
+ phy_detach(pep->phy);
+
+ iounmap(pep->base);
+ pep->base = NULL;
+ unregister_netdev(dev);
+ flush_scheduled_work();
+ free_netdev(dev);
+ platform_set_drvdata(pdev, NULL);
+ return 0;
+}
+
+static void pxa168_eth_shutdown(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ eth_port_reset(dev);
+}
+
+#ifdef CONFIG_PM
+static int pxa168_eth_resume(struct platform_device *pdev)
+{
+ return -ENOSYS;
+}
+
+static int pxa168_eth_suspend(struct platform_device *pdev, pm_message_t state)
+{
+ return -ENOSYS;
+}
+
+#else
+#define pxa168_eth_resume NULL
+#define pxa168_eth_suspend NULL
+#endif
+
+static struct platform_driver pxa168_eth_driver = {
+ .probe = pxa168_eth_probe,
+ .remove = pxa168_eth_remove,
+ .shutdown = pxa168_eth_shutdown,
+ .resume = pxa168_eth_resume,
+ .suspend = pxa168_eth_suspend,
+ .driver = {
+ .name = DRIVER_NAME,
+ },
+};
+
+static int __init pxa168_init_module(void)
+{
+ return platform_driver_register(&pxa168_eth_driver);
+}
+
+static void __exit pxa168_cleanup_module(void)
+{
+ platform_driver_unregister(&pxa168_eth_driver);
+}
+
+module_init(pxa168_init_module);
+module_exit(pxa168_cleanup_module);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Ethernet driver for Marvell PXA168");
+MODULE_ALIAS("platform:pxa168_eth");
diff --git a/include/linux/pxa168_eth.h b/include/linux/pxa168_eth.h
new file mode 100644
index 0000000..152981c
--- /dev/null
+++ b/include/linux/pxa168_eth.h
@@ -0,0 +1,20 @@
+/*
+ *pxa168 ethernet platform device data definition file.
+ */
+#ifndef __LINUX_PXA168_ETH_H
+#define __LINUX_PXA168_ETH_H
+
+struct pxa168_eth_platform_data {
+ int phy_addr;
+
+ /* If speed is 0, then speed and duplex are autonegotiated. */
+ int speed; /* 0, SPEED_10, SPEED_100 */
+ int duplex; /* DUPLEX_HALF or DUPLEX_FULL */
+
+ /* init callback is used for board specific initialization
+ * e.g on Aspenite its used to initialize the PHY transceiver.
+ */
+ int (*init)(void);
+};
+
+#endif /* __LINUX_PXA168_ETH_H */
--
1.5.3.3
^ permalink raw reply related
* Re: [net-next] net: More verbose message for too-many-orphans.
From: David Miller @ 2010-08-10 8:48 UTC (permalink / raw)
To: greearb; +Cc: netdev
In-Reply-To: <1281380402-14608-1-git-send-email-greearb@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Date: Mon, 9 Aug 2010 12:00:02 -0700
> The original message doesn't give much clue as to what
> is actually going wrong or how to fix it.
>
> Signed-off-by: Ben Greear <greearb@candelatech.com>
Dumping a bunch of values obtainable via sysctl is pointless.
The only non-sysctl value you're dumping is 'orphans' and based upon
the sysctl values you can determine whether it made the check inside
of tcp_too_many_orphans() trigger, and in what way.
I'm not applying this, sorry.
^ permalink raw reply
* Re: Missing device binding relating to tcp_v4_send_reset?
From: David Miller @ 2010-08-10 8:48 UTC (permalink / raw)
To: greearb; +Cc: netdev, kaber
In-Reply-To: <4C603EF2.9010902@candelatech.com>
From: Ben Greear <greearb@candelatech.com>
Date: Mon, 09 Aug 2010 10:46:26 -0700
> This snippet is from some patches Patrick did for me some time
> back. I think the rest of his work has been merged upstream, but
> this patch was not. I'm honestly not sure if it's needed or not,
> but we've been running with it for at least a year or so and it's
> been working fine for us.
There is no reason at all to force a reply to a packet to
go out of the same interface as the packet which triggered
that reply arrived upon.
^ permalink raw reply
* [PATCH] iputils: firewall mark option in tracepath/tracepath6
From: Антон Д. @ 2010-08-10 9:17 UTC (permalink / raw)
To: netdev
diff --git a/tracepath.c b/tracepath.c
index 81c22e9..6675f14 100644
--- a/tracepath.c
+++ b/tracepath.c
@@ -42,6 +42,7 @@ __u16 base_port;
const int overhead = 28;
int mtu = 65535;
+int mark = 0;
int hops_to = -1;
int hops_from = -1;
int no_resolve = 0;
@@ -285,7 +286,7 @@ static void usage(void) __attribute((noreturn));
static void usage(void)
{
- fprintf(stderr, "Usage: tracepath [-n] [-b] [-l <len>]
<destination>[/<port>]\n");
+ fprintf(stderr, "Usage: tracepath [-n] [-b] [-l <len>] [-m <mark>]
<destination>[/<port>]\n");
exit(-1);
}
@@ -299,7 +300,7 @@ main(int argc, char **argv)
char *p;
int ch;
- while ((ch = getopt(argc, argv, "nbh?l:")) != EOF) {
+ while ((ch = getopt(argc, argv, "nbh?l:m:")) != EOF) {
switch(ch) {
case 'n':
no_resolve = 1;
@@ -313,6 +314,9 @@ main(int argc, char **argv)
exit(1);
}
break;
+ case 'm':
+ mark = atoi(optarg);
+ break;
default:
usage();
}
@@ -345,6 +349,12 @@ main(int argc, char **argv)
}
memcpy(&target.sin_addr, he->h_addr, 4);
+ if (mark) {
+ if (setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1) {
+ fprintf(stderr, "Warning: Failed to set mark %d\n", mark);
+ }
+ }
+
on = IP_PMTUDISC_PROBE;
if (setsockopt(fd, SOL_IP, IP_MTU_DISCOVER, &on, sizeof(on)) &&
(on = IP_PMTUDISC_DO,
diff --git a/tracepath6.c b/tracepath6.c
index 5cc7424..5d08c62 100644
--- a/tracepath6.c
+++ b/tracepath6.c
@@ -52,6 +52,7 @@ socklen_t targetlen;
__u16 base_port;
int overhead = 48;
+int mark = 0;
int mtu = 128000;
int hops_to = -1;
int hops_from = -1;
@@ -359,7 +360,7 @@ static void usage(void) __attribute((noreturn));
static void usage(void)
{
- fprintf(stderr, "Usage: tracepath6 [-n] [-b] [-l <len>]
<destination>[/<port>]\n");
+ fprintf(stderr, "Usage: tracepath6 [-n] [-b] [-l <len>] [-m <mark>]
<destination>[/<port>]\n");
exit(-1);
}
@@ -375,7 +376,7 @@ int main(int argc, char **argv)
int gai;
char pbuf[NI_MAXSERV];
- while ((ch = getopt(argc, argv, "nbh?l:")) != EOF) {
+ while ((ch = getopt(argc, argv, "nbh?l:m:")) != EOF) {
switch(ch) {
case 'n':
no_resolve = 1;
@@ -389,6 +390,9 @@ int main(int argc, char **argv)
exit(1);
}
break;
+ case 'm':
+ mark = atoi(optarg);
+ break;
default:
usage();
}
@@ -439,6 +443,12 @@ int main(int argc, char **argv)
}
freeaddrinfo(ai0);
+ if (mark) {
+ if (setsockopt(fd, SOL_SOCKET, SO_MARK, &mark, sizeof(mark)) == -1) {
+ fprintf(stderr, "Warning: Failed to set mark %d\n", mark);
+ }
+ }
+
switch (family) {
case AF_INET6:
mtu = 128000;
^ permalink raw reply related
* Re: [RFC PATCH 2/2] igb/ixgbe: add code to trigger function reset if reset_devices is set
From: Kenji Kaneshige @ 2010-08-10 9:31 UTC (permalink / raw)
To: David Woodhouse
Cc: David Miller, jeffrey.t.kirsher, jbarnes, netdev, linux-pci,
alexander.h.duyck
In-Reply-To: <1281025664.8720.28.camel@localhost>
(2010/08/06 1:27), David Woodhouse wrote:
> On Sun, 2010-08-01 at 01:15 -0700, David Miller wrote:
>> From: Jeff Kirsher<jeffrey.t.kirsher@intel.com>
>> Date: Fri, 30 Jul 2010 17:59:12 -0700
>>
>>> From: Alexander Duyck<alexander.h.duyck@intel.com>
>>>
>>> This change makes it so that both igb and ixgbe can trigger a full pcie
>>> function reset if the reset_devices kernel parameter is defined. The main
>>> reason for adding this is that kdump can cause serious issues when the
>>> kdump kernel resets the IOMMU while DMA transactions are still occurring.
>>>
>>> Signed-off-by: Alexander Duyck<alexander.h.duyck@intel.com>
>>> Signed-off-by: Jeff Kirsher<jeffrey.t.kirsher@intel.com>
>>
>> I tend to disagree with the essence of this change.
>>
>> Which is that we should add workaround after workaround for things
>> that aren't functioning properly in kdump and kexec.
>>
>> They should have a pass that shuts devices down properly, so that this
>> kind of stuff doesn't need to happen in the kernel we then boot into.
>
> For a normal kexec, arguably true.
>
> But in the kdump case, the original kernel has *crashed* and we really
> don't have that option -- we need to jump *straight* to the new kernel
> and have it reset the hardware.
>
> The device driver really *ought* to be able to reset the hardware from
> whatever state it's in when the new kernel starts up. Anything less is
> broken, and reminds me of those crappy drivers that only work after a
> soft-reboot from Windows.
>
> Most drivers *do* quite happily initialise their device and reliably get
> it into a known state; it's just that this particular hardware goes into
> a *particularly* stroppy fit when it gets a DMA master abort (which is
> what happens when the IOMMU stops it from scribbling into memory after
> the new kernel has taken over).
>
>> What happens on non-PCIE systems then? Do they just lose when this
>> happens?
>
> If they have a device that's this broken, and the driver can't get it
> into a working state any other way, then yes -- I don't see any way to
> *avoid* them losing.
What about asserting secondary RST# on the bridge?
It would not work for devices on the root bus though.
Thanks,
Kenji Kaneshige
^ permalink raw reply
* Re: [RFC] [PATCH] Don't destroy TCP sockets twice
From: Herbert Xu @ 2010-08-10 10:24 UTC (permalink / raw)
To: Andi Kleen; +Cc: netdev
In-Reply-To: <20100810083040.GB6801@basil.fritz.box>
On Tue, Aug 10, 2010 at 10:30:40AM +0200, Andi Kleen wrote:
.
> This simple patch demonstrates double destroy. I have patches for showing
> the more complicated case too, but they're much more ugly.
Andi, I know you're seeing the problem, but I need to udnerstand
why, and this patch doesn't really answer the why part :)
So did you figure out why was calling it first (I presume you
know who called it the second time since you've got the back
trace)?
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [RFC] [PATCH] Don't destroy TCP sockets twice
From: Andi Kleen @ 2010-08-10 10:32 UTC (permalink / raw)
To: Herbert Xu; +Cc: Andi Kleen, netdev
In-Reply-To: <20100810102421.GA28030@gondor.apana.org.au>
On Tue, Aug 10, 2010 at 06:24:21AM -0400, Herbert Xu wrote:
> On Tue, Aug 10, 2010 at 10:30:40AM +0200, Andi Kleen wrote:
> .
> > This simple patch demonstrates double destroy. I have patches for showing
> > the more complicated case too, but they're much more ugly.
>
> Andi, I know you're seeing the problem, but I need to udnerstand
> why, and this patch doesn't really answer the why part :)
>
> So did you figure out why was calling it first (I presume you
> know who called it the second time since you've got the back
> trace)?
Yes I stored the backtrace of the first caller in the ugly debug
patches and dumped that on the second destroy. It was tcp_done the
first time.
Also did the same for tcp_sk() and there it was the fin sending.
I agree that tcp_close() should skip it in theory but I saw
it anyways :/
-Andi
^ permalink raw reply
* Re: [RFC] [PATCH] Don't destroy TCP sockets twice
From: Herbert Xu @ 2010-08-10 10:39 UTC (permalink / raw)
To: Andi Kleen; +Cc: netdev
In-Reply-To: <20100810103206.GC6801@basil.fritz.box>
On Tue, Aug 10, 2010 at 12:32:06PM +0200, Andi Kleen wrote:
>
> Yes I stored the backtrace of the first caller in the ugly debug
> patches and dumped that on the second destroy. It was tcp_done the
> first time.
>
> Also did the same for tcp_sk() and there it was the fin sending.
>
> I agree that tcp_close() should skip it in theory but I saw
> it anyways :/
So I presume the second caller was tcp_close? That means we have
a serious bug in our stack, as if the socket is already in the
CLOSE state then tcp_close should have short-circuited.
This means that something is changing the TCP socket state after
going into CLOSE. Can you try adding your debug backtrace patch to
tcp_set_state to see if anybody is indeed changing the socket
state after going into CLOSE (and more importantly who is changing
it)?
Thanks,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: [RFC PATCH 1/2] pci: add function reset call that can be used inside of probe
From: Kenji Kaneshige @ 2010-08-10 10:39 UTC (permalink / raw)
To: Jeff Kirsher; +Cc: davem, jbarnes, netdev, linux-pci, Alexander Duyck
In-Reply-To: <20100731005803.32625.6891.stgit@localhost.localdomain>
(2010/07/31 9:58), Jeff Kirsher wrote:
> From: Alexander Duyck<alexander.h.duyck@intel.com>
>
> This change makes it so that there are several new calls available.
>
> The first is __pci_reset_dev which works similar to pci_reset_dev, however
> it does not obtain the device lock. This is important as I found several
> cases such as __pci_reset_function in which the call was obtaining the
> device lock even though the lock had yet to be initialized. In addition if
> one wishes to do such a reset during probe it will hang since the device
> lock is already being held.
>
> The second change that was added was a function named
> pci_reset_device_function. This function is similar to pci_reset_function
> however it does not hold the device lock and so it as well can be called
> during the driver probe routine.
>
> Signed-off-by: Alexander Duyck<alexander.h.duyck@intel.com>
> Signed-off-by: Jeff Kirsher<jeffrey.t.kirsher@intel.com>
> ---
>
> drivers/pci/pci.c | 74 +++++++++++++++++++++++++++++++++++++++++++--------
> include/linux/pci.h | 1 +
> 2 files changed, 64 insertions(+), 11 deletions(-)
>
> diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
> index 60f30e7..1421bc7 100644
> --- a/drivers/pci/pci.c
> +++ b/drivers/pci/pci.c
> @@ -2445,17 +2445,14 @@ static int pci_parent_bus_reset(struct pci_dev *dev, int probe)
> return 0;
> }
>
> -static int pci_dev_reset(struct pci_dev *dev, int probe)
> +static int __pci_dev_reset(struct pci_dev *dev, int probe)
> {
> int rc;
>
> might_sleep();
>
> - if (!probe) {
> + if (!probe)
> pci_block_user_cfg_access(dev);
> - /* block PM suspend, driver probe, etc. */
> - device_lock(&dev->dev);
> - }
>
> rc = pci_dev_specific_reset(dev, probe);
> if (rc != -ENOTTY)
> @@ -2474,11 +2471,26 @@ static int pci_dev_reset(struct pci_dev *dev, int probe)
> goto done;
>
> rc = pci_parent_bus_reset(dev, probe);
> +
> done:
> - if (!probe) {
> - device_unlock(&dev->dev);
> + if (!probe)
> pci_unblock_user_cfg_access(dev);
> - }
> +
> + return rc;
> +}
> +
> +static int pci_dev_reset(struct pci_dev *dev, int probe)
> +{
> + int rc;
> +
> + /* block PM suspend, driver probe, etc. */
> + if (!probe)
> + device_lock(&dev->dev);
> +
> + rc = __pci_dev_reset(dev, probe);
> +
> + if (!probe)
> + device_unlock(&dev->dev);
>
> return rc;
> }
> @@ -2502,7 +2514,7 @@ done:
> */
> int __pci_reset_function(struct pci_dev *dev)
> {
> - return pci_dev_reset(dev, 0);
> + return __pci_dev_reset(dev, 0);
> }
> EXPORT_SYMBOL_GPL(__pci_reset_function);
>
> @@ -2519,7 +2531,7 @@ EXPORT_SYMBOL_GPL(__pci_reset_function);
> */
> int pci_probe_reset_function(struct pci_dev *dev)
> {
> - return pci_dev_reset(dev, 1);
> + return __pci_dev_reset(dev, 1);
> }
>
> /**
> @@ -2542,7 +2554,7 @@ int pci_reset_function(struct pci_dev *dev)
> {
> int rc;
>
> - rc = pci_dev_reset(dev, 1);
> + rc = __pci_dev_reset(dev, 1);
> if (rc)
> return rc;
>
> @@ -2563,6 +2575,46 @@ int pci_reset_function(struct pci_dev *dev)
> EXPORT_SYMBOL_GPL(pci_reset_function);
>
> /**
> + * pci_reset_device_function - quiesce and reinitialize a PCI device function
> + * @dev: PCI device to reset
> + *
> + * Some devices allow an individual function to be reset without affecting
> + * other functions in the same device. The PCI device must be responsive
> + * to PCI config space in order to use this function.
> + *
> + * This function is very similar to pci_reset_function, however this function
> + * does not obtain the device lock during the reset. This is due to the fact
> + * that the call is meant to be used during probe if the reset_devices
> + * kernel parameter is set.
> + *
> + * Returns 0 if the device function was successfully reset or negative if the
> + * device doesn't support resetting a single function.
> + */
> +int pci_reset_device_function(struct pci_dev *dev)
> +{
> + int rc;
> +
> + rc = __pci_dev_reset(dev, 1);
> + if (rc)
> + return rc;
> +
> + pci_save_state(dev);
> +
> + /*
> + * both INTx and MSI are disabled after the Interrupt Disable bit
> + * is set and the Bus Master bit is cleared.
> + */
> + pci_write_config_word(dev, PCI_COMMAND, PCI_COMMAND_INTX_DISABLE);
> +
> + rc = __pci_dev_reset(dev, 0);
Could you tell me why you need to program command register before reset?
"MSI enable" and "Bus Master" bits are cleared by the reset. Furthermore,
resetting the device clears the "Interrupt Disable bit", even though it
was set just before the rest. So I'm a little confused.
Thanks,
Kenji Kaneshige
^ permalink raw reply
* Re: [PATCH] net: add Fast Ethernet driver for PXA168.
From: Lennert Buytenhek @ 2010-08-10 11:40 UTC (permalink / raw)
To: Philip Rakity
Cc: Sachin Sanap, netdev@vger.kernel.org, Ashish Karkare,
Prabhanjan Sarnaik, eric.y.miao@gmail.com, Mark Brown
In-Reply-To: <26AE03C2-9D1A-4E63-82E3-DD47BD451B70@marvell.com>
On Fri, Aug 06, 2010 at 08:44:02AM -0700, Philip Rakity wrote:
> You should change
>
> >>> + skb = dev_alloc_skb(MAX_PKT_SIZE + ETH_HW_IP_ALIGN);
>
> >>
>
> to allocatie ADDITIONAL prepend space in the header. If you are doing
> ethernet to 802.11 routing or bridging then the wireless driver will
> not have enough space in front of the header to prepend its headers
> without having to allocate additional space.
This seems like something that, should you want to handle it, should be
handled centrally (e.g. by conditionally increasing NET_SKB_PAD or so)
and not hardcoded into one specific driver only.
^ permalink raw reply
* Re: [PATCH 1/1] Bluetooth: hidp: Add support for hidraw HIDIOCGFEATURE and HIDIOCSFEATURE
From: Jiri Kosina @ 2010-08-10 11:46 UTC (permalink / raw)
To: Alan Ott
Cc: Marcel Holtmann, David S Miller, Michael Poole, Bastien Nocera,
Eric Dumazet, linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <4C4878C2.9000903-yzvJWuRpmD1zbRFIqnYvSA@public.gmane.org>
On Thu, 22 Jul 2010, Alan Ott wrote:
> > that the ioctl() API is synchronous is fine to me, however pushing that
> > down to the transport drivers seems wrong to me. I think the HID core
> > should be able to handle a fully asynchronous transport driver. I know
> > that with the USB subsystem you are little bit spoiled here, but for
> > Bluetooth it is not the case. And in the end even using the asynchronous
> > USB URB calls would be nice as well.
> >
>
> How are the URB calls better than using the synchronous calls? (see below)
Hi,
I think this was the last mail in the thread so far, right?
> > So why not make the core actually wait for responses from the transport
> > driver.
>
> Because this makes the USB side a lot more complicated, and it would
> introduce transport specific code into the core. Further, it would
> involve the transport driver calling hidraw with _every_ single packet
> it receives. Further, it would have to call hidraw with HANDSHAKE
> protocol error packets as well.
>
> > I would make the transport drivers a lot simpler in the long
> > run.
>
> It would make the USB transport driver and drivers/hid/hidraw much more
> complicated right now, at the expense of making the BT transport driver
> marginally simpler (and I'm not even convinced whether it would really be
> simpler). (see below for more)
Seconded.
> > And I know that most likely besides Bluetooth and USB you won't see
> > another, but you never know.
> >
> I just don't understand the objection. In each transport type, the waiting
> will have to be done in a different way. USB and BT are different enough that
> this is the case already, without having to imagine future buses which use
> HID. In BT, you have to check each packet which comes back from the BT network
> to see whether it is the response packet that hidraw is waiting for. Further,
> you have to check for HANDSHAKE packets indicating protocol error. Where
> better for this to be done than in hidp? Further, how can this possibly happen
> in drivers/hid/hidraw, as it doesn't know about the details of bluetooth to
> make this determination, and why should it? In my last email (
> http://lkml.org/lkml/2010/7/9/231 ) to which I got no response, I laid out how
> doing the blocking in drivers/hid/hidraw would only make all the parts except
> bluetooth more complicated (including the core, and the USB side), and would
> also introduce bluetooth-specific things into the core.
>
> Further, you're saying that using the asynchronous USB URB calls would be a
> benefit. How is it a benefit to replace a single function call which does
> exactly what I want, with a set of asynchronous calls and then adding my own
> blocking to make it do the same thing? This sounds to me like it would be 1:
> more text, 2: duplication of code, 3: error prone. I can't understand how this
> is of benefit. Please explain to me what I'm missing.
>
> In theory, what you're saying makes sense. Making common code and logic
> actually common is always good. In practice though, in this case, I submit
> that there really isn't any commonality, and the only way for there to be
> commonality is to do the USB side the hard way. Further, drivers/hid/hidraw
> can't wait for a bluetooth packet without having code that's
> bluetooth-specific. It seems just that simple to me.
>
> I'll give it some more thought, and take another look at the code to see if
> there's something obvious that I'm missing. If you know what I'm missing in my
> understanding of the problem, please tell me :)
Marcel, did you have time to review Alan's explanation a little bit?
I must say I would really like to have this feature merged, but of course
not if you completely disagree .. but then we'll have to find some
consensus. Currently Alan's summary above quite aligns with my opinion.
Thanks,
--
Jiri Kosina
SUSE Labs, Novell Inc.
^ permalink raw reply
* Re: e1000e crashes with 2.6.34.x and ThinkPad T60
From: Marc Haber @ 2010-08-10 12:02 UTC (permalink / raw)
To: Chuck Ebbert
Cc: Marc Haber, Allan, Bruce W, Linux Kernel Developers,
Linux Kernel Network Developers,
e1000-devel@lists.sourceforge.net
In-Reply-To: <20100806014610.2bd64d44@katamari>
On Fri, Aug 06, 2010 at 01:46:10AM -0400, Chuck Ebbert wrote:
> On Fri, 30 Jul 2010 14:56:14 +0200
> Marc Haber <mh+linux-kernel@zugschlus.de> wrote:
>
> > Capabilities: <access denied>
>
> That's not very useful.
>
> The pcie capabilities are completely missing.
Again, apologizes. The attached lspci -vvv is from 2.6.35, right after
the first freeze with this kernel version.
Greetings
Marc
00:00.0 Host bridge: Intel Corporation Mobile 945GM/PM/GMS, 943/940GML and 945GT Express Memory Controller Hub (rev 03)
Subsystem: Lenovo ThinkPad T60
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort+ >SERR- <PERR- INTx-
Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=09 <?>
00:01.0 PCI bridge: Intel Corporation Mobile 945GM/PM/GMS, 943/940GML and 945GT Express PCI Express Root Port (rev 03) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Bus: primary=00, secondary=01, subordinate=01, sec-latency=0
I/O behind bridge: 00002000-00002fff
Memory behind bridge: ee100000-ee1fffff
Prefetchable memory behind bridge: 00000000d8000000-00000000dfffffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort+ <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA+ VGA+ MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [88] Subsystem: Lenovo Device 2014
Capabilities: [80] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [90] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0300c Data: 4161
Capabilities: [a0] Express (v1) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- RBE- FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
LnkCap: Port #2, Speed 2.5GT/s, Width x16, ASPM L0s L1, Latency L0 <1us, L1 <4us
ClockPM- Surprise- LLActRep- BwNot-
LnkCtl: ASPM L0s L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x16, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug- Surprise-
Slot #1, PowerLimit 75.000W; Interlock- NoCompl-
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
Control: AttnInd Off, PwrInd On, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
Changed: MRL- PresDet+ LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed+ WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
Status: NegoPending- InProgress-
Capabilities: [140 v1] Root Complex Link
Desc: PortNumber=02 ComponentID=01 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=01 AssocRCRB- LinkType=MemMapped LinkValid+
Addr: 00000000fed19000
Kernel driver in use: pcieport
00:1b.0 Audio device: Intel Corporation N10/ICH 7 Family High Definition Audio Controller (rev 02)
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin B routed to IRQ 49
Region 0: Memory at ee400000 (64-bit, non-prefetchable) [size=16K]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=55mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [60] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000fee0300c Data: 41c1
Capabilities: [70] Express (v1) Root Complex Integrated Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <64ns, L1 <1us
ExtTag- RBE- FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #0, Speed unknown, Width x0, ASPM unknown, Latency L0 <64ns, L1 <1us
ClockPM- Surprise- LLActRep- BwNot-
LnkCtl: ASPM Disabled; Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed unknown, Width x0, TrErr- Train- SlotClk- DLActive- BWMgmt- ABWMgmt-
Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed- WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
Status: NegoPending- InProgress-
VC1: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed- WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=1 ArbSelect=Fixed TC/VC=80
Status: NegoPending- InProgress-
Capabilities: [130 v1] Root Complex Link
Desc: PortNumber=0f ComponentID=02 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=02 AssocRCRB- LinkType=MemMapped LinkValid+
Addr: 00000000fed1c000
Kernel driver in use: HDA Intel
00:1c.0 PCI bridge: Intel Corporation N10/ICH 7 Family PCI Express Port 1 (rev 02) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Bus: primary=00, secondary=02, subordinate=02, sec-latency=0
I/O behind bridge: 00003000-00003fff
Memory behind bridge: ee000000-ee0fffff
Prefetchable memory behind bridge: 00000000c0000000-00000000c01fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA+ VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Express (v1) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
ExtTag- RBE- FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr+ UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #1, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <256ns, L1 <4us
ClockPM- Surprise- LLActRep+ BwNot-
LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+
Slot #2, PowerLimit 6.500W; Interlock- NoCompl-
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet+ CmdCplt- HPIrq+ LinkChg-
Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
Changed: MRL- PresDet- LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0300c Data: 4169
Capabilities: [90] Subsystem: Lenovo Device 2011
Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed+ WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
Status: NegoPending- InProgress-
VC1: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable- ID=0 ArbSelect=Fixed TC/VC=00
Status: NegoPending- InProgress-
Capabilities: [180 v1] Root Complex Link
Desc: PortNumber=01 ComponentID=02 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=02 AssocRCRB- LinkType=MemMapped LinkValid+
Addr: 00000000fed1c001
Kernel driver in use: pcieport
00:1c.1 PCI bridge: Intel Corporation N10/ICH 7 Family PCI Express Port 2 (rev 02) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Bus: primary=00, secondary=03, subordinate=03, sec-latency=0
I/O behind bridge: 00004000-00005fff
Memory behind bridge: ec000000-edffffff
Prefetchable memory behind bridge: 00000000e4000000-00000000e40fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA+ VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Express (v1) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
ExtTag- RBE- FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #2, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <256ns, L1 <4us
ClockPM- Surprise- LLActRep+ BwNot-
LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive+ BWMgmt- ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+
Slot #3, PowerLimit 6.500W; Interlock- NoCompl-
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet+ Interlock-
Changed: MRL- PresDet+ LinkState+
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0300c Data: 4171
Capabilities: [90] Subsystem: Lenovo Device 2011
Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed+ WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=01
Status: NegoPending- InProgress-
VC1: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable- ID=0 ArbSelect=Fixed TC/VC=00
Status: NegoPending- InProgress-
Capabilities: [180 v1] Root Complex Link
Desc: PortNumber=02 ComponentID=02 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=02 AssocRCRB- LinkType=MemMapped LinkValid+
Addr: 00000000fed1c001
Kernel driver in use: pcieport
00:1c.2 PCI bridge: Intel Corporation N10/ICH 7 Family PCI Express Port 3 (rev 02) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Bus: primary=00, secondary=04, subordinate=0b, sec-latency=0
I/O behind bridge: 00006000-00007fff
Memory behind bridge: e8000000-e9ffffff
Prefetchable memory behind bridge: 00000000e4100000-00000000e41fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA+ VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Express (v1) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
ExtTag- RBE- FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #3, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <1us, L1 <4us
ClockPM- Surprise- LLActRep+ BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x0, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+
Slot #4, PowerLimit 6.500W; Interlock- NoCompl-
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet+ CmdCplt- HPIrq+ LinkChg-
Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
Changed: MRL- PresDet- LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0300c Data: 4179
Capabilities: [90] Subsystem: Lenovo Device 2011
Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed+ WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
Status: NegoPending- InProgress-
VC1: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable- ID=0 ArbSelect=Fixed TC/VC=00
Status: NegoPending- InProgress-
Capabilities: [180 v1] Root Complex Link
Desc: PortNumber=03 ComponentID=02 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=02 AssocRCRB- LinkType=MemMapped LinkValid+
Addr: 00000000fed1c001
Kernel driver in use: pcieport
00:1c.3 PCI bridge: Intel Corporation N10/ICH 7 Family PCI Express Port 4 (rev 02) (prog-if 00 [Normal decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Bus: primary=00, secondary=0c, subordinate=13, sec-latency=0
I/O behind bridge: 00008000-00009fff
Memory behind bridge: ea000000-ebffffff
Prefetchable memory behind bridge: 00000000e4200000-00000000e42fffff
Secondary status: 66MHz- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA+ VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [40] Express (v1) Root Port (Slot+), MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s unlimited, L1 unlimited
ExtTag- RBE- FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd- ExtTag- PhantFunc- AuxPwr- NoSnoop-
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr+ TransPend-
LnkCap: Port #4, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <1us, L1 <4us
ClockPM- Surprise- LLActRep+ BwNot-
LnkCtl: ASPM Disabled; RCB 64 bytes Disabled- Retrain- CommClk-
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x0, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
SltCap: AttnBtn- PwrCtrl- MRL- AttnInd- PwrInd- HotPlug+ Surprise+
Slot #5, PowerLimit 6.500W; Interlock- NoCompl-
SltCtl: Enable: AttnBtn- PwrFlt- MRL- PresDet- CmdCplt- HPIrq- LinkChg-
Control: AttnInd Unknown, PwrInd Unknown, Power- Interlock-
SltSta: Status: AttnBtn- PowerFlt- MRL- CmdCplt- PresDet- Interlock-
Changed: MRL- PresDet- LinkState-
RootCtl: ErrCorrectable- ErrNon-Fatal- ErrFatal- PMEIntEna- CRSVisible-
RootCap: CRSVisible-
RootSta: PME ReqID 0000, PMEStatus- PMEPending-
Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0300c Data: 4181
Capabilities: [90] Subsystem: Lenovo Device 2011
Capabilities: [a0] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [100 v1] Virtual Channel
Caps: LPEVC=0 RefClk=100ns PATEntryBits=1
Arb: Fixed+ WRR32- WRR64- WRR128-
Ctrl: ArbSelect=Fixed
Status: InProgress-
VC0: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable+ ID=0 ArbSelect=Fixed TC/VC=ff
Status: NegoPending- InProgress-
VC1: Caps: PATOffset=00 MaxTimeSlots=1 RejSnoopTrans-
Arb: Fixed+ WRR32- WRR64- WRR128- TWRR128- WRR256-
Ctrl: Enable- ID=0 ArbSelect=Fixed TC/VC=00
Status: NegoPending- InProgress-
Capabilities: [180 v1] Root Complex Link
Desc: PortNumber=04 ComponentID=02 EltType=Config
Link0: Desc: TargetPort=00 TargetComponent=02 AssocRCRB- LinkType=MemMapped LinkValid+
Addr: 00000000fed1c001
Kernel driver in use: pcieport
00:1d.0 USB Controller: Intel Corporation N10/ICH 7 Family USB UHCI Controller #1 (rev 02) (prog-if 00 [UHCI])
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin A routed to IRQ 16
Region 4: I/O ports at 1800 [size=32]
Kernel driver in use: uhci_hcd
00:1d.1 USB Controller: Intel Corporation N10/ICH 7 Family USB UHCI Controller #2 (rev 02) (prog-if 00 [UHCI])
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin B routed to IRQ 17
Region 4: I/O ports at 1820 [size=32]
Kernel driver in use: uhci_hcd
00:1d.2 USB Controller: Intel Corporation N10/ICH 7 Family USB UHCI Controller #3 (rev 02) (prog-if 00 [UHCI])
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin C routed to IRQ 18
Region 4: I/O ports at 1840 [size=32]
Kernel driver in use: uhci_hcd
00:1d.3 USB Controller: Intel Corporation N10/ICH 7 Family USB UHCI Controller #4 (rev 02) (prog-if 00 [UHCI])
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin D routed to IRQ 19
Region 4: I/O ports at 1860 [size=32]
Kernel driver in use: uhci_hcd
00:1d.7 USB Controller: Intel Corporation N10/ICH 7 Family USB2 EHCI Controller (rev 02) (prog-if 20 [EHCI])
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin D routed to IRQ 19
Region 0: Memory at ee404000 (32-bit, non-prefetchable) [size=1K]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=375mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [58] Debug port: BAR=1 offset=00a0
Kernel driver in use: ehci_hcd
00:1e.0 PCI bridge: Intel Corporation 82801 Mobile PCI Bridge (rev e2) (prog-if 01 [Subtractive decode])
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Bus: primary=00, secondary=15, subordinate=18, sec-latency=32
I/O behind bridge: 0000a000-0000dfff
Memory behind bridge: e4300000-e7ffffff
Prefetchable memory behind bridge: 00000000e0000000-00000000e3ffffff
Secondary status: 66MHz- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort+ <SERR- <PERR-
BridgeCtl: Parity- SERR- NoISA- VGA- MAbort- >Reset- FastB2B-
PriDiscTmr- SecDiscTmr- DiscTmrStat- DiscTmrSERREn-
Capabilities: [50] Subsystem: Lenovo Device 2013
00:1f.0 ISA bridge: Intel Corporation 82801GBM (ICH7-M) LPC Interface Bridge (rev 02)
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Capabilities: [e0] Vendor Specific Information: Len=0c <?>
00:1f.1 IDE interface: Intel Corporation 82801G (ICH7 Family) IDE Controller (rev 02) (prog-if 8a [Master SecP PriP])
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O+ Mem- BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin C routed to IRQ 16
Region 0: I/O ports at 01f0 [size=8]
Region 1: I/O ports at 03f4 [size=1]
Region 2: I/O ports at 0170 [size=8]
Region 3: I/O ports at 0374 [size=1]
Region 4: I/O ports at 1880 [size=16]
Kernel driver in use: ata_piix
00:1f.2 SATA controller: Intel Corporation 82801GBM/GHM (ICH7 Family) SATA AHCI Controller (rev 02) (prog-if 01 [AHCI 1.0])
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx+
Status: Cap+ 66MHz+ UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0
Interrupt: pin B routed to IRQ 45
Region 0: I/O ports at 18c8 [size=8]
Region 1: I/O ports at 18ac [size=4]
Region 2: I/O ports at 18c0 [size=8]
Region 3: I/O ports at 18a8 [size=4]
Region 4: I/O ports at 18b0 [size=16]
Region 5: Memory at ee404400 (32-bit, non-prefetchable) [size=1K]
Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit-
Address: fee0300c Data: 4189
Capabilities: [70] Power Management version 2
Flags: PMEClk- DSI- D1- D2- AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot+,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Kernel driver in use: ahci
00:1f.3 SMBus: Intel Corporation N10/ICH 7 Family SMBus Controller (rev 02)
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O+ Mem- BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx-
Status: Cap- 66MHz- UDF- FastB2B+ ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Interrupt: pin A routed to IRQ 23
Region 4: I/O ports at 18e0 [size=32]
Kernel driver in use: i801_smbus
01:00.0 VGA compatible controller: ATI Technologies Inc Radeon Mobility X1400 (prog-if 00 [VGA controller])
Subsystem: Lenovo Thinkpad T60 model 2007
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 46
Region 0: Memory at d8000000 (32-bit, prefetchable) [size=128M]
Region 1: I/O ports at 2000 [size=256]
Region 2: Memory at ee100000 (32-bit, non-prefetchable) [size=64K]
[virtual] Expansion ROM at ee120000 [disabled] [size=128K]
Capabilities: [50] Power Management version 2
Flags: PMEClk- DSI- D1+ D2+ AuxCurrent=0mA PME(D0-,D1-,D2-,D3hot-,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [58] Express (v1) Legacy Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <4us, L1 unlimited
ExtTag+ AttnBtn- AttnInd- PwrInd- RBE- FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr- FatalErr- UnsuppReq- AuxPwr- TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x16, ASPM L0s L1, Latency L0 <64ns, L1 <1us
ClockPM- Surprise- LLActRep- BwNot-
LnkCtl: ASPM L0s L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM- AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x16, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
Capabilities: [80] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000fee0300c Data: 4191
Kernel driver in use: radeon
02:00.0 Ethernet controller: Intel Corporation 82573L Gigabit Ethernet Controller
Subsystem: Lenovo ThinkPad T60
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 47
Region 0: Memory at ee000000 (32-bit, non-prefetchable) [size=128K]
Region 2: I/O ports at 3000 [size=32]
Capabilities: [c8] Power Management version 2
Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold+)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=1 PME-
Capabilities: [d0] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000fee0300c Data: 41e1
Capabilities: [e0] Express (v1) Endpoint, MSI 00
DevCap: MaxPayload 256 bytes, PhantFunc 0, Latency L0s <512ns, L1 <64us
ExtTag- AttnBtn- AttnInd- PwrInd- RBE- FLReset-
DevCtl: Report errors: Correctable+ Non-Fatal+ Fatal+ Unsupported+
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 512 bytes
DevSta: CorrErr- UncorrErr+ FatalErr- UnsuppReq+ AuxPwr+ TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <128ns, L1 <64us
ClockPM+ Surprise- LLActRep- BwNot-
LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO+ CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
AERCap: First Error Pointer: 14, GenCap- CGenEn- ChkCap- ChkEn-
Capabilities: [140 v1] Device Serial Number 00-16-41-ff-ff-aa-be-37
Kernel driver in use: e1000e
03:00.0 Network controller: Intel Corporation PRO/Wireless 3945ABG [Golan] Network Connection (rev 02)
Subsystem: Intel Corporation ThinkPad R60e/X60s
Control: I/O- Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR+ FastB2B- DisINTx+
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=fast >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 0, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 48
Region 0: Memory at edf00000 (32-bit, non-prefetchable) [size=4K]
Capabilities: [c8] Power Management version 2
Flags: PMEClk- DSI+ D1- D2- AuxCurrent=0mA PME(D0+,D1-,D2-,D3hot+,D3cold-)
Status: D0 NoSoftRst- PME-Enable- DSel=0 DScale=0 PME-
Capabilities: [d0] MSI: Enable+ Count=1/1 Maskable- 64bit+
Address: 00000000fee0100c Data: 41b9
Capabilities: [e0] Express (v1) Legacy Endpoint, MSI 00
DevCap: MaxPayload 128 bytes, PhantFunc 0, Latency L0s <512ns, L1 unlimited
ExtTag- AttnBtn- AttnInd- PwrInd- RBE- FLReset-
DevCtl: Report errors: Correctable- Non-Fatal- Fatal- Unsupported-
RlxdOrd+ ExtTag- PhantFunc- AuxPwr- NoSnoop+
MaxPayload 128 bytes, MaxReadReq 128 bytes
DevSta: CorrErr- UncorrErr+ FatalErr- UnsuppReq+ AuxPwr- TransPend-
LnkCap: Port #0, Speed 2.5GT/s, Width x1, ASPM L0s L1, Latency L0 <128ns, L1 <64us
ClockPM+ Surprise- LLActRep- BwNot-
LnkCtl: ASPM L1 Enabled; RCB 64 bytes Disabled- Retrain- CommClk+
ExtSynch- ClockPM+ AutWidDis- BWInt- AutBWInt-
LnkSta: Speed 2.5GT/s, Width x1, TrErr- Train- SlotClk+ DLActive- BWMgmt- ABWMgmt-
Capabilities: [100 v1] Advanced Error Reporting
UESta: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq+ ACSViol-
UEMsk: DLP- SDES- TLP- FCP- CmpltTO- CmpltAbrt- UnxCmplt- RxOF- MalfTLP- ECRC- UnsupReq- ACSViol-
UESvrt: DLP+ SDES- TLP- FCP+ CmpltTO- CmpltAbrt- UnxCmplt- RxOF+ MalfTLP+ ECRC- UnsupReq- ACSViol-
CESta: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
CEMsk: RxErr- BadTLP- BadDLLP- Rollover- Timeout- NonFatalErr-
AERCap: First Error Pointer: 14, GenCap- CGenEn- ChkCap- ChkEn-
Capabilities: [140 v1] Device Serial Number 00-18-de-ff-ff-9d-59-43
Kernel driver in use: iwl3945
15:00.0 CardBus bridge: Texas Instruments PCI1510 PC card Cardbus Controller
Subsystem: Lenovo ThinkPad T60/R60 series
Control: I/O+ Mem+ BusMaster+ SpecCycle- MemWINV- VGASnoop- ParErr- Stepping- SERR- FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- <TAbort- <MAbort- >SERR- <PERR- INTx-
Latency: 168, Cache Line Size: 64 bytes
Interrupt: pin A routed to IRQ 16
Region 0: Memory at e4300000 (32-bit, non-prefetchable) [size=4K]
Bus: primary=15, secondary=16, subordinate=17, sec-latency=176
Memory window 0: e0000000-e3fff000 (prefetchable)
Memory window 1: c4000000-c7fff000
I/O window 0: 0000a000-0000a0ff
I/O window 1: 0000a400-0000a4ff
BridgeCtl: Parity- SERR- ISA- VGA- MAbort- >Reset+ 16bInt+ PostWrite+
16-bit legacy interface ports at 0001
Kernel driver in use: yenta_cardbus
--
-----------------------------------------------------------------------------
Marc Haber | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany | lose things." Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature | How to make an American Quilt | Fax: *49 3221 2323190
^ permalink raw reply
* Re: e1000e crashes with 2.6.34.x and ThinkPad T60
From: Marc Haber @ 2010-08-10 12:04 UTC (permalink / raw)
To: Tantilov, Emil S
Cc: Marc Haber, Linux Kernel Developers,
Linux Kernel Network Developers, Allan, Bruce W
In-Reply-To: <EA929A9653AAE14F841771FB1DE5A13660024083FE@rrsmsx501.amr.corp.intel.com>
On Wed, Aug 04, 2010 at 12:23:45PM -0600, Tantilov, Emil S wrote:
> Looking at your lspci output - your system has a slightly different HW, but I don't know if this is significant.
>
> Are you loading the kernel with any parameters (cat /proc/cmdline)?
BOOT_IMAGE=/vmlinuz-2.6.35-zgws1 root=/dev/mapper/root ro
resume=/dev/mapper/swap0 quiet splash radeon.modeset=1
> Do you have firewall configured (iptables -L)?
I am working pretty intensively with virtual machines which are natted
here and there. I have a handful of MASQUERADE rules in the
nat/POSTROUTING chain, but that's it.
> Also now that 2.6.35 is out - could you give it a try and see if the situation had improved?
Tried, no improvement.
Greetings
Marc
--
-----------------------------------------------------------------------------
Marc Haber | "I don't trust Computers. They | Mailadresse im Header
Mannheim, Germany | lose things." Winona Ryder | Fon: *49 621 72739834
Nordisch by Nature | How to make an American Quilt | Fax: *49 3221 2323190
^ permalink raw reply
* Re: [PATCH 1/1] Bluetooth: hidp: Add support for hidraw HIDIOCGFEATURE and HIDIOCSFEATURE
From: Marcel Holtmann @ 2010-08-10 12:12 UTC (permalink / raw)
To: Jiri Kosina
Cc: Alan Ott, David S Miller, Michael Poole, Bastien Nocera,
Eric Dumazet, linux-bluetooth-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
In-Reply-To: <alpine.LNX.2.00.1008101344480.29919-ztGlSCb7Y1iN3ZZ/Hiejyg@public.gmane.org>
Hi Jiri,
> > > that the ioctl() API is synchronous is fine to me, however pushing that
> > > down to the transport drivers seems wrong to me. I think the HID core
> > > should be able to handle a fully asynchronous transport driver. I know
> > > that with the USB subsystem you are little bit spoiled here, but for
> > > Bluetooth it is not the case. And in the end even using the asynchronous
> > > USB URB calls would be nice as well.
> > >
> >
> > How are the URB calls better than using the synchronous calls? (see below)
>
> Hi,
>
> I think this was the last mail in the thread so far, right?
>
> > > So why not make the core actually wait for responses from the transport
> > > driver.
> >
> > Because this makes the USB side a lot more complicated, and it would
> > introduce transport specific code into the core. Further, it would
> > involve the transport driver calling hidraw with _every_ single packet
> > it receives. Further, it would have to call hidraw with HANDSHAKE
> > protocol error packets as well.
> >
> > > I would make the transport drivers a lot simpler in the long
> > > run.
> >
> > It would make the USB transport driver and drivers/hid/hidraw much more
> > complicated right now, at the expense of making the BT transport driver
> > marginally simpler (and I'm not even convinced whether it would really be
> > simpler). (see below for more)
>
> Seconded.
>
> > > And I know that most likely besides Bluetooth and USB you won't see
> > > another, but you never know.
> > >
> > I just don't understand the objection. In each transport type, the waiting
> > will have to be done in a different way. USB and BT are different enough that
> > this is the case already, without having to imagine future buses which use
> > HID. In BT, you have to check each packet which comes back from the BT network
> > to see whether it is the response packet that hidraw is waiting for. Further,
> > you have to check for HANDSHAKE packets indicating protocol error. Where
> > better for this to be done than in hidp? Further, how can this possibly happen
> > in drivers/hid/hidraw, as it doesn't know about the details of bluetooth to
> > make this determination, and why should it? In my last email (
> > http://lkml.org/lkml/2010/7/9/231 ) to which I got no response, I laid out how
> > doing the blocking in drivers/hid/hidraw would only make all the parts except
> > bluetooth more complicated (including the core, and the USB side), and would
> > also introduce bluetooth-specific things into the core.
> >
> > Further, you're saying that using the asynchronous USB URB calls would be a
> > benefit. How is it a benefit to replace a single function call which does
> > exactly what I want, with a set of asynchronous calls and then adding my own
> > blocking to make it do the same thing? This sounds to me like it would be 1:
> > more text, 2: duplication of code, 3: error prone. I can't understand how this
> > is of benefit. Please explain to me what I'm missing.
> >
> > In theory, what you're saying makes sense. Making common code and logic
> > actually common is always good. In practice though, in this case, I submit
> > that there really isn't any commonality, and the only way for there to be
> > commonality is to do the USB side the hard way. Further, drivers/hid/hidraw
> > can't wait for a bluetooth packet without having code that's
> > bluetooth-specific. It seems just that simple to me.
> >
> > I'll give it some more thought, and take another look at the code to see if
> > there's something obvious that I'm missing. If you know what I'm missing in my
> > understanding of the problem, please tell me :)
>
> Marcel, did you have time to review Alan's explanation a little bit?
>
> I must say I would really like to have this feature merged, but of course
> not if you completely disagree .. but then we'll have to find some
> consensus. Currently Alan's summary above quite aligns with my opinion.
my opinion is still that we should make the core do the async handling.
I think that we let USB dictate how APIs for HID should look like.
However that is maybe fine anyway since the Bluetooth HID guys where not
really inventive since they copying USB HID for the better and mostly
for the worst. Especially since Bluetooth doesn't have the endpoint
direction limits like USB does. Anyhow, just get the patches re-based
and re-submitted and I can have a second look.
Regards
Marcel
^ permalink raw reply
* Dead Config Option STMMAC_ETH?
From: Christian Dietrich @ 2010-08-10 12:28 UTC (permalink / raw)
To: David S. Miller, Giuseppe Cavallaro, netdev, linux-kernel
Cc: vamos-dev@i4.informatik.uni-erlangen.de
Hi all!
As part of the VAMOS[0] research project at the University of
Erlangen we are looking at multiple integrity errors in linux'
configuration system.
I've been running a check on the drivers/net/stmmac sourcetree for
config Items not defined in Kconfig and found such a case. Sourcecode
blocks depending on these Items are not reachable from a vanilla
kernel -- dead code. I've seen such dead blocks made on purpose
e.g. while integrating new features into the kernel but generally
they're just useless.
As far as i can see in drivers/net/stmmac/Kconfig STMMAC_ETH and several
depending flags are dead in the linux vanilla kernel, because it depends
on CPU_SUBTYPE_ST40, but there isn't a Kconfig option for that. But
f96691872439ab2071171d4531c4a95b5d493ae5 suggests, that support for this
ST40 plattform was removed in 2007.
There seems to be, that there was much effort on the stmmac drivers in
the last few months, so i just wanted to ask if this problem is known.
Regards
Christian Dietrich
[0] http://vamos1.informatik.uni-erlangen.de
--
(λ x . x x) (λ x . x x) -- See how beatiful the lambda is
No documentation is better than bad documentation
-- Das Ausdrucken dieser Mail wird urheberrechtlich verfolgt.
^ permalink raw reply
* Re: [PATCH v2] net: add Fast Ethernet driver for PXA168.
From: Lennert Buytenhek @ 2010-08-10 12:33 UTC (permalink / raw)
To: Sachin Sanap
Cc: Philip Rakity, netdev@vger.kernel.org, Ashish Karkare,
Prabhanjan Sarnaik, eric.y.miao@gmail.com, Mark Brown
In-Reply-To: <1281429004.17990.2.camel@pe-lt522.marvell.com>
On Tue, Aug 10, 2010 at 02:00:04PM +0530, Sachin Sanap wrote:
> * Headroom in SKB for 802.11 not included in the patch since that
> varies based on 802.11 a/b/g/n.
I don't think this is true?
(The 11a/b/n on-the-air preambles are of different lengths (and are
sent at different rates), but that isn't visible to software.)
> +#define ETH_HW_IP_ALIGN 2 /* hw aligns IP header */
> +#define ETH_DATA_LEN 1500
> +#define MAX_PKT_SIZE 1518
How about (stacked) VLANs?
Is the hardware entirely unable to receive larger packets than this, or
is it capable of receiving such packets but e.g. with loss of hardware
receive checksum offloading?
(I guess the hardware can't do RX checksum offload at all since I see
no references to skb->ip_summed and CHECKSUM_*?)
> +#define MAX_DESCS_PER_HIGH (60)
> +#define TX_DESC_COUNT_LOW (10)
These don't seem used.
> +struct pxa168_eth_private {
>
> [...]
>
> + /* Size of Tx Ring per queue */
> + int tx_ring_size;
>
> [...]
>
> + /* Size of Rx Ring per queue */
> + int rx_ring_size;
If you're not going to let the tx/rx ring size be runtime configurable
(like they are in mv643xx_eth), you might as well leave these as defines.
> +static void ethernet_phy_set_addr(struct pxa168_eth_private *pep, int phy_addr)
> +{
> + u32 reg_data;
> +
> + reg_data = rdl(pep, PHY_ADDRESS);
> + reg_data &= ~(0x1f);
No need for the parentheses.
> +static inline u8 flip_8_bits(u8 x)
> +{
> + return (((x) & 0x01) << 3) | (((x) & 0x002) << 1)
> + | (((x) & 0x04) >> 1) | (((x) & 0x008) >> 3)
0x02, 0x08
> + addr0 = (mac_addr[5] >> 2) & 0x03f;
> + addr1 = (mac_addr[5] & 0x003) | (((mac_addr[4] & 0x7f)) << 2);
> + addr2 = ((mac_addr[4] & 0x80) >> 7) | mac_addr[3] << 1;
> + addr3 = (mac_addr[2] & 0x0ff) | ((mac_addr[1] & 1) << 8);
0x34, 0x03, 0xff
> + if (i == HOP_NUMBER) {
> + if (!del) {
> + printk(KERN_INFO "%s: table section is full\n",
> + __FILE__);
> + return -ENOSPC;
> + } else
What does it mean in practice if this happens? (The error message
could be a bit more descriptive.)
> +static void pxa168_eth_set_rx_mode(struct net_device *dev)
> +{
> + struct pxa168_eth_private *pep = netdev_priv(dev);
> + struct netdev_hw_addr *ha;
> + u32 val;
> +
> + val = rdl(pep, PORT_CONFIG);
> + if (dev->flags & IFF_PROMISC)
> + val |= PCR_PM;
> + else
> + val &= ~PCR_PM;
> + wrl(pep, PORT_CONFIG, val);
> + netdev_for_each_mc_addr(ha, dev)
> + update_hash_table_mac_address(pep, NULL, ha->addr);
> +}
1. Don't indent with spaces.
2. This will never remove old multicast MAC addresses?
> + pep->work_todo &= ~(WORK_TX_DONE);
Doesn't need parentheses.
> +static int rxq_process(struct net_device *dev, int budget)
> +{
> + struct pxa168_eth_private *pep = netdev_priv(dev);
> + struct net_device_stats *stats = &dev->stats;
> + unsigned int received_packets = 0;
> + struct sk_buff *skb;
> +
> + while (budget-- > 0) {
> +
> + int rx_next_curr_desc, rx_curr_desc, rx_used_desc;
No need for an empty line.
> +static int pxa168_eth_collect_events(struct pxa168_eth_private *pep,
> + struct net_device *dev)
> +{
> + u32 icr;
> + int ret = 0;
> +
> + icr = rdl(pep, INT_CAUSE);
> + if (0x00 == icr)
icr == 0
> + wrl(pep, INT_CAUSE, icr ^ 0xffffffff);
~icr ?
> + /* Extended Port Configuration */
> + wrl(pep,
> + PORT_CONFIG_EXT, PCXR_2BSM | /* Two byte suffix aligns IP hdr */
Prefix?
> + dma_free_coherent(NULL, pep->tx_desc_area_size,
> + pep->p_tx_desc_area, pep->tx_desc_dma);
BTW, you should pass in a struct device * to the DMA allocation
functions.
> + err = request_irq(dev->irq, pxa168_eth_int_handler,
> + IRQF_DISABLED , dev->name, dev);
Superfluous space before the comma.
> +static void eth_tx_submit_descs_for_skb(struct pxa168_eth_private *pep,
> + struct sk_buff *skb)
> +{
> + int tx_index;
> + struct tx_desc *desc;
> + int length;
> +
> + tx_index = eth_alloc_tx_desc_index(pep);
> + desc = &pep->p_tx_desc_area[tx_index];
> + length = skb->len;
> + pep->tx_skb[tx_index] = skb;
> + desc->byte_cnt = length;
> + desc->buf_ptr = dma_map_single(NULL, skb->data, length, DMA_TO_DEVICE);
> + wmb();
> + desc->cmd_sts = BUF_OWNED_BY_DMA | TX_GEN_CRC | TX_FIRST_DESC |
> + TX_ZERO_PADDING | TX_LAST_DESC;
> + if (unlikely(!(pep->tx_desc_count % (pep->tx_ring_size / 4))))
> + desc->cmd_sts |= TX_EN_INT;
Is this intended to only generate transmit completion interrupts for
every N packets?
If so, you cannot delay kfree_skb()ing a transmitted skb indefinitely.
If you want to batch TX completion interrupts, you at least have to put
in a timeout.
Also, the descriptor is in device-visible memory, and BUF_OWNED_BY_DMA
becomes visible to the device as soon as you do the preceding store to
desc->cmd_sts -- you cannot then go back and alter that field, as you
could race with the device clearing BUF_OWNED_BY_DMA.
> +static int pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
> +{
> + struct pxa168_eth_private *pep = netdev_priv(dev);
> + struct net_device_stats *stats = &dev->stats;
> +
> + eth_tx_submit_descs_for_skb(pep, skb);
In mv643xx_eth, txq_submit_*() are much larger because they have to deal
with scatter-gather transmit. Since you don't support that, you might
as well just inline this function here.
> +static int pxa168_smi_read(struct mii_bus *bus, int phy_addr, int regnum)
> +{
> + int val;
> + struct pxa168_eth_private *pep = bus->priv;
> + int i = 0;
> +
> + /* wait for the SMI register to become available */
> + for (i = 0; (val = rdl(pep, SMI)) & SMI_BUSY; i++) {
> + if (i == PHY_WAIT_ITERATIONS) {
> + printk(KERN_ERR
> + "pxa168 PHY timeout, val=0x%x\n", val);
> + return -ETIMEDOUT;
> + }
> + udelay(1);
> + }
> + wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) | SMI_OP_R);
> + /* now wait for the data to be valid */
> + for (i = 0; !((val = rdl(pep, SMI)) & SMI_R_VALID); i++) {
> + if (i == PHY_WAIT_ITERATIONS) {
> + printk(KERN_ERR
> + "pxa168 PHY RD timeout, val=0x%x\n", val);
> + return -ETIMEDOUT;
> + }
> + udelay(1);
> + }
> + return val & 0xffff;
> +}
This can end up busy-waiting (i.e. hogging the CPU) for twice 500 us,
i.e. 1 msec. Isn't there a SMI completion interrupt you can use, or
at least yield the cpu by sleeping for a bit?
> +static int pxa168_smi_write(struct mii_bus *bus, int phy_addr, int regnum,
> + u16 value)
> +{
> + struct pxa168_eth_private *pep = bus->priv;
> + int i;
> +
> + /* wait for the SMI register to become available */
> + for (i = 0; rdl(pep, SMI) & SMI_BUSY; i++) {
> + if (i == PHY_WAIT_ITERATIONS) {
> + printk(KERN_ERR "pxa168 PHY busy timeout.\n");
> + return -ETIMEDOUT;
> + }
> + udelay(1);
> + }
> + wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) |
> + SMI_OP_W | (value & 0xffff));
I would wait here for the write to complete, otherwise you can't report
errors due to the slave address not responding.
> + clk = clk_get(&pdev->dev, "MFUCLK");
> + if (IS_ERR(clk)) {
> + printk(KERN_ERR "fast Ethernet failed to get clock\n");
At least stick the name of the driver in here.
> + /* init callback is used for board specific initialization
> + * e.g on Aspenite its used to initialize the PHY transceiver.
> + */
> + int (*init)(void);
Is resetting the PHY not enough?
^ permalink raw reply
* Re: Auto generation of IPv6 link local address
From: Jon Smirl @ 2010-08-10 12:49 UTC (permalink / raw)
To: Michał Mirosław; +Cc: Netdev
In-Reply-To: <AANLkTi=zmZHsJpMRxk5wa56Uh0fKPkBaLT1hp0uZzax+@mail.gmail.com>
2010/8/10 Michał Mirosław <mirqus@gmail.com>:
> 2010/8/10 Jon Smirl <jonsmirl@gmail.com>:
>> When I bring my Ethernet interface up it automatically gets a link
>> local IPv6 address.
>>
>> eth3 Link encap:Ethernet HWaddr 00:1b:21:59:65:32
>> inet addr:192.168.1.8 Bcast:192.168.1.255 Mask:255.255.255.0
>> inet6 addr: fe80::21b:21ff:fe59:6532/64 Scope:Link -->
>> Missing from my driver
>> UP BROADCAST RUNNING MULTICAST MTU:1500 Metric:1
>> RX packets:1836635 errors:0 dropped:0 overruns:0 frame:0
>> TX packets:1283010 errors:0 dropped:0 overruns:0 carrier:0
>> collisions:0 txqueuelen:1000
>> RX bytes:2259859914 (2.2 GB) TX bytes:121836850 (121.8 MB)
>> Interrupt:16 Memory:dbd60000-dbd80000
>>
>> I'm writing a device driver for new 802.15.4 hardware. When I bring it
>> up I don't get an automatic IPv6 link local address. What controls
>> whether an adapter gets a link local address added or not? My driver
>> should get one so I must have something wrong in my code.
>>
>> wpan0 Link encap:IEEE 802.15.4 HWaddr 00:50:c2:ff:fe:a8:a8:c5
>> UP BROADCAST RUNNING NOARP MTU:1280 Metric:1
>> RX packets:0 errors:0 dropped:0 overruns:0 frame:0
>> TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
>> collisions:0 txqueuelen:10
>> RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
>
> addrconf_notify() in linux-2.6.34/net/ipv6/addrconf.c does not have
> code for IEEE 802.15.4. I don't know much about 802.15.4, but if IPv6
> with static addresses works over it, then adding support for
> autogenerated addresses should be easy (just addrconf_dev_config() and
> ipv6_generate_eui64()?).
It was easy...
I added a ipv6_generate_eui64() since the addresses are already 64b.
wpan0 Link encap:IEEE 802.15.4 HWaddr 00:50:c2:ff:fe:a8:a8:c5
inet6 addr: fe80::50:c2ff:fea8:c545/64 Scope:Link
inet6 addr: aaaa::1/64 Scope:Global
UP BROADCAST RUNNING NOARP MTU:1280 Metric:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions:0 txqueuelen:10
RX bytes:0 (0.0 B) TX bytes:0 (0.0 B)
Back to working on my 6lowpan implementation.
http://en.wikipedia.org/wiki/6lowpan
>
> Best Regards,
> Michał Mirosław
>
--
Jon Smirl
jonsmirl@gmail.com
^ permalink raw reply
* Re: [09/38] xen: netfront: explicitly generate arp_notify event after migration.
From: Ian Campbell @ 2010-08-10 13:07 UTC (permalink / raw)
To: Greg KH
Cc: Jeremy Fitzhardinge, xen-devel@lists.xensource.com,
David S. Miller, Stephen Hemminger, linux-kernel@vger.kernel.org,
stable@kernel.org, netdev@vger.kernel.org,
akpm@linux-foundation.org, torvalds@linux-foundation.org,
stable-review@kernel.org, alan@lxorguk.ukuu.org.uk
In-Reply-To: <20100806183200.858950407@clark.site>
Hi Greg,
Looks like I forgot to request this for 2.6.32 too, could you queue it
up there as well?
It depends on the previous patch in this series (arp_notify: allow
drivers to explicitly request a notification event.).
Thanks,
Ian.
On Fri, 2010-08-06 at 19:30 +0100, Greg KH wrote:
> 2.6.35-stable review patch. If anyone has any objections, please let us know.
>
> ------------------
>
> From: Ian Campbell <Ian.Campbell@citrix.com>
>
> commit 592970675c9522bde588b945388c7995c8b51328 upstream.
>
> Use newly introduced netif_notify_peers() method to ensure a gratuitous ARP is
> generated after a migration.
>
> Signed-off-by: Ian Campbell <ian.campbell@citrix.com>
> Cc: Stephen Hemminger <shemminger@linux-foundation.org>
> Cc: Jeremy Fitzhardinge <jeremy@goop.org>
> Cc: David S. Miller <davem@davemloft.net>
> Cc: netdev@vger.kernel.org
> Cc: xen-devel@lists.xensource.com
> Signed-off-by: David S. Miller <davem@davemloft.net>
> Signed-off-by: Greg Kroah-Hartman <gregkh@suse.de>
>
> ---
> drivers/net/xen-netfront.c | 1 +
> 1 file changed, 1 insertion(+)
>
> --- a/drivers/net/xen-netfront.c
> +++ b/drivers/net/xen-netfront.c
> @@ -1621,6 +1621,7 @@ static void backend_changed(struct xenbu
> if (xennet_connect(netdev) != 0)
> break;
> xenbus_switch_state(dev, XenbusStateConnected);
> + netif_notify_peers(netdev);
> break;
>
> case XenbusStateClosing:
>
>
^ permalink raw reply
* Re: [Uclinux-dist-devel] [PATCH 1/2] net: dsa: introduce STPID switch tagging handling code
From: Lennert Buytenhek @ 2010-08-10 14:05 UTC (permalink / raw)
To: Mike Frysinger; +Cc: Karl Beldan, netdev, uclinux-dist-devel
In-Reply-To: <AANLkTinNiE1BE=HuwVG2Tom922XJXxQDB-JMsPYimPTk@mail.gmail.com>
On Thu, Jul 29, 2010 at 01:50:45PM -0400, Mike Frysinger wrote:
> >>> >> + source_port = dsa_header[1] & 0x03;
> >>> >> + if (source_port >= DSA_MAX_PORTS || ds->ports[source_port] == NULL)
> >>> >> + goto out_drop;
> >>> >> +
> >>> >> + if (((dsa_header[0] & ETH_P_8021QH) == ETH_P_8021QH) &&
> >>> >
> >>> > This is bogus -- what it does is:
> >>> >
> >>> > if ((dsa_header[0] & 0x81) == 0x81)
> >>> >
> >>> > It doesn't look like you need to mask here at all.
> >>>
> >>> where does it say dsa_header[0] will always have 0x81 set ?
> >>
> >> Eh?
> >>
> >> This code is checking whether the packet has a STPID tag on it or not.
> >> A STPID tag exists if the first 12 nibbles are 0x810.
> >>
> >> You are checking whether the first 8 nibbles of this are equal to 0x81
> >> by doing:
> >>
> >> if ((byte & 0x81) == 0x81)
> >>
> >> What if the first byte is 0x93? Or 0xc5?
> >
> > that was my point. should it be masking or doing a raw compare ?
>
> and the answer is ... ? so i can send an updated patch ;)
From what I understand, you should just be checking for equality with
0x81 in the first byte, as that is what indicates presence of the STPID
tag.
Is the hardware you're doing this on available somewhere for me to
try things out on?
^ permalink raw reply
* Re: Missing device binding relating to tcp_v4_send_reset?
From: Ben Greear @ 2010-08-10 14:22 UTC (permalink / raw)
To: David Miller; +Cc: netdev, kaber
In-Reply-To: <20100810.014846.258126767.davem@davemloft.net>
On 08/10/2010 01:48 AM, David Miller wrote:
> From: Ben Greear<greearb@candelatech.com>
> Date: Mon, 09 Aug 2010 10:46:26 -0700
>
>> This snippet is from some patches Patrick did for me some time
>> back. I think the rest of his work has been merged upstream, but
>> this patch was not. I'm honestly not sure if it's needed or not,
>> but we've been running with it for at least a year or so and it's
>> been working fine for us.
>
> There is no reason at all to force a reply to a packet to
> go out of the same interface as the packet which triggered
> that reply arrived upon.
Ok, in my case I *did* want this behaviour..it makes send-to-self,
BIND_TO_DEVICE and virtual routers and such work properly if I
recall correctly.
Would you consider a sysctl to enable this feature, with it disabled
by default? Please note there are similar sysctls for ICMP already...
Thanks,
Ben
--
Ben Greear <greearb@candelatech.com>
Candela Technologies Inc http://www.candelatech.com
^ permalink raw reply
* Re: Yet another bridge netfilter crash
From: Herbert Xu @ 2010-08-10 15:19 UTC (permalink / raw)
To: Changli Gao; +Cc: Patrick McHardy, Stephen Hemminger, netdev
In-Reply-To: <AANLkTikpCOrkPqOkahXBFFoH6bqTKhA-+_mUy0qGrRnq@mail.gmail.com>
On Tue, Aug 10, 2010 at 06:39:42AM +0800, Changli Gao wrote:
>
> How about always using the skb->nf_bridge of the skb last received in
> a defrag queue as the nf_bridge of the final defraged skb? I have
> posted a patch doing such thing.
> http://patchwork.ozlabs.org/patch/60904/
I'd rather just drop the fragment (and maybe fail the whole
reassembly) if you detect nf_bridge mismatches.
Reassembling fragments from two interfaces is one thing, but
knowingly reassembling fragments across two bridges is just
wrong.
Cheers,
--
Email: Herbert Xu <herbert@gondor.apana.org.au>
Home Page: http://gondor.apana.org.au/~herbert/
PGP Key: http://gondor.apana.org.au/~herbert/pubkey.txt
^ permalink raw reply
* Re: e1000e crashes with 2.6.34.x and ThinkPad T60
From: Allan, Bruce W @ 2010-08-10 16:34 UTC (permalink / raw)
To: Marc Haber, Tantilov, Emil S
Cc: Network Developers, e1000-devel@lists.sf.net,
Linux Kernel Developers, Linux
In-Reply-To: <20100810120458.GB21511@torres.zugschlus.de>
On Tuesday, August 10, 2010 5:05 AM, Marc Haber wrote:
> On Wed, Aug 04, 2010 at 12:23:45PM -0600, Tantilov, Emil S wrote:
>> Looking at your lspci output - your system has a slightly different
>> HW, but I don't know if this is significant.
>>
>> Are you loading the kernel with any parameters (cat /proc/cmdline)?
>
> BOOT_IMAGE=/vmlinuz-2.6.35-zgws1 root=/dev/mapper/root ro
> resume=/dev/mapper/swap0 quiet splash radeon.modeset=1
>
>> Do you have firewall configured (iptables -L)?
>
> I am working pretty intensively with virtual machines which are natted
> here and there. I have a handful of MASQUERADE rules in the
> nat/POSTROUTING chain, but that's it.
>
>> Also now that 2.6.35 is out - could you give it a try and see if the
>> situation had improved?
>
> Tried, no improvement.
>
> Greetings
> Marc
[adding e1000-devel, the Intel wired ethernet developers mailing list]
We have had other recent reports of issues with this part that are due to
ASPM L1 being enabled. Would you please try disabling L1 after the driver
is loaded as follows (assuming your adapter is still PCI bus/device/number
02:00.0 as indicated in the lspci output you provided earlier):
1) First check the hexadecimal value of the LnkCtl register -
# setpci -s 2:0.0 0xf0
2) Disable ASPM (both L0s and L1) by zeroing out bits 0 and 1 in the value
returned by the previous step. For example, if it returned 42 (hex 42,
that is) -
# setpci -s 2:0.0 0xf0=0x40
3) Confirm ASPM is disabled by checking the output from lspci again.
Please let us know if this helps your situation, thanks.
Bruce.
------------------------------------------------------------------------------
This SF.net email is sponsored by
Make an app they can't live without
Enter the BlackBerry Developer Challenge
http://p.sf.net/sfu/RIM-dev2dev
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox