From 0ce68c74162ce288cfd214dd126b8d03b8b7a8ed Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Sat, 28 Apr 2007 15:36:40 -0500 Subject: pasemi_mac: A couple of minor bugfixes. Bugfixes: * Move the wake_queue logic from tx_intr to clean_tx * Always do wake_queue even if queue wasn't full before clean since it's safe to do * Fix polarity in checks in pasemi_mac_close Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 76fe9dd8e84..bde833542b6 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -476,6 +476,8 @@ static int pasemi_mac_clean_tx(struct pasemi_mac *mac) mac->tx->next_to_clean += count; spin_unlock_irqrestore(&mac->tx->lock, flags); + netif_wake_queue(mac->netdev); + return count; } @@ -510,9 +512,6 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) struct net_device *dev = data; struct pasemi_mac *mac = netdev_priv(dev); unsigned int reg; - int was_full; - - was_full = mac->tx->next_to_clean - mac->tx->next_to_use == TX_RING_SIZE; if (!(*mac->tx_status & PAS_STATUS_INT)) return IRQ_NONE; @@ -526,9 +525,6 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); - if (was_full) - netif_wake_queue(dev); - return IRQ_HANDLED; } @@ -660,40 +656,37 @@ static int pasemi_mac_close(struct net_device *dev) pci_read_config_dword(mac->dma_pdev, PAS_DMA_TXCHAN_TCMDSTA(mac->dma_txch), &stat); - if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT) + if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)) break; cond_resched(); } - if (!(stat & PAS_DMA_TXCHAN_TCMDSTA_ACT)) { + if (stat & PAS_DMA_TXCHAN_TCMDSTA_ACT) dev_err(&mac->dma_pdev->dev, "Failed to stop tx channel\n"); - } for (retries = 0; retries < MAX_RETRIES; retries++) { pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_CCMDSTA(mac->dma_rxch), &stat); - if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT) + if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)) break; cond_resched(); } - if (!(stat & PAS_DMA_RXCHAN_CCMDSTA_ACT)) { + if (stat & PAS_DMA_RXCHAN_CCMDSTA_ACT) dev_err(&mac->dma_pdev->dev, "Failed to stop rx channel\n"); - } for (retries = 0; retries < MAX_RETRIES; retries++) { pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), &stat); - if (stat & PAS_DMA_RXINT_RCMDSTA_ACT) + if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT)) break; cond_resched(); } - if (!(stat & PAS_DMA_RXINT_RCMDSTA_ACT)) { + if (stat & PAS_DMA_RXINT_RCMDSTA_ACT) dev_err(&mac->dma_pdev->dev, "Failed to stop rx interface\n"); - } /* Then, disable the channel. This must be done separately from * stopping, since you can't disable when active. -- cgit v1.2.3 From cee505db2459aa100a4c3619b8178ec323f1d11e Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 7 May 2007 23:49:25 +0200 Subject: myri10ge: support new firmware counters Add dropped_pause, dropped_bad_phy, dropped_bad_crc32, dropped_unicast_filtered to the set of ethtool counters. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 9 ++++++++- drivers/net/myri10ge/myri10ge_mcp.h | 6 +++++- 2 files changed, 13 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 16e3c4315e8..b48b988cf87 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -1355,7 +1355,9 @@ static const char myri10ge_gstrings_stats[][ETH_GSTRING_LEN] = { "tx_req", "tx_done", "rx_small_cnt", "rx_big_cnt", "wake_queue", "stop_queue", "watchdog_resets", "tx_linearized", "link_changes", "link_up", "dropped_link_overflow", - "dropped_link_error_or_filtered", "dropped_multicast_filtered", + "dropped_link_error_or_filtered", + "dropped_pause", "dropped_bad_phy", "dropped_bad_crc32", + "dropped_unicast_filtered", "dropped_multicast_filtered", "dropped_runt", "dropped_overrun", "dropped_no_small_buffer", "dropped_no_big_buffer" }; @@ -1412,6 +1414,11 @@ myri10ge_get_ethtool_stats(struct net_device *netdev, data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_overflow); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_link_error_or_filtered); + data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_pause); + data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_phy); + data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_bad_crc32); + data[i++] = + (unsigned int)ntohl(mgp->fw_stats->dropped_unicast_filtered); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_multicast_filtered); data[i++] = (unsigned int)ntohl(mgp->fw_stats->dropped_runt); diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h index 29463b301a8..ee6261db2a5 100644 --- a/drivers/net/myri10ge/myri10ge_mcp.h +++ b/drivers/net/myri10ge/myri10ge_mcp.h @@ -219,7 +219,11 @@ enum myri10ge_mcp_cmd_status { struct mcp_irq_data { /* add new counters at the beginning */ - __be32 future_use[5]; + __be32 future_use[1]; + __be32 dropped_pause; + __be32 dropped_unicast_filtered; + __be32 dropped_bad_crc32; + __be32 dropped_bad_phy; __be32 dropped_multicast_filtered; /* 40 Bytes */ __be32 send_done_count; -- cgit v1.2.3 From 772a815804ae778aee7fcf937f3d29ab218ecdc7 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 7 May 2007 23:49:59 +0200 Subject: myri10ge: update firmware headers Update myri10ge firmware headers to those of 1.4.16. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge_mcp.h | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge_mcp.h b/drivers/net/myri10ge/myri10ge_mcp.h index ee6261db2a5..a1d2a22296a 100644 --- a/drivers/net/myri10ge/myri10ge_mcp.h +++ b/drivers/net/myri10ge/myri10ge_mcp.h @@ -200,6 +200,13 @@ enum myri10ge_mcp_cmd_type { /* data0, data1 = bus addr, * data2 = sizeof(struct mcp_irq_data) from driver point of view, allows * adding new stuff to mcp_irq_data without changing the ABI */ + + MXGEFW_CMD_UNALIGNED_TEST, + /* same than DMA_TEST (same args) but abort with UNALIGNED on unaligned + * chipset */ + + MXGEFW_CMD_UNALIGNED_STATUS + /* return data = boolean, true if the chipset is known to be unaligned */ }; enum myri10ge_mcp_cmd_status { @@ -212,7 +219,8 @@ enum myri10ge_mcp_cmd_status { MXGEFW_CMD_ERROR_HASH_ERROR, MXGEFW_CMD_ERROR_BAD_PORT, MXGEFW_CMD_ERROR_RESOURCES, - MXGEFW_CMD_ERROR_MULTICAST + MXGEFW_CMD_ERROR_MULTICAST, + MXGEFW_CMD_ERROR_UNALIGNED }; #define MXGEFW_OLD_IRQ_DATA_LEN 40 @@ -228,6 +236,10 @@ struct mcp_irq_data { /* 40 Bytes */ __be32 send_done_count; +#define MXGEFW_LINK_DOWN 0 +#define MXGEFW_LINK_UP 1 +#define MXGEFW_LINK_MYRINET 2 +#define MXGEFW_LINK_UNKNOWN 3 __be32 link_up; __be32 dropped_link_overflow; __be32 dropped_link_error_or_filtered; -- cgit v1.2.3 From 2f76216fe071a67fc110a85a10b1eca038379e11 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 7 May 2007 23:50:37 +0200 Subject: myri10ge: fix restoring of multicast list after reset Don't count on whatever implementation artifact preserves the multicast list across a reset cmd, and setup multicast filtering as part of our reset routine. The setting of allmulti when adopting firmware with the rx-filter broadcast bug is also moved into the multicast setup routine where it belongs. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index b48b988cf87..3245357a06f 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -290,6 +290,8 @@ MODULE_PARM_DESC(myri10ge_wcfifo, "Enable WC Fifo when WC is enabled\n"); #define myri10ge_pio_copy(to,from,size) __iowrite64_copy(to,from,size/8) +static void myri10ge_set_multicast_list(struct net_device *dev); + static inline void put_be32(__be32 val, __be32 __iomem * p) { __raw_writel((__force __u32) val, (__force void __iomem *)p); @@ -820,10 +822,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) mgp->rx_done.cnt = 0; mgp->link_changes = 0; status = myri10ge_update_mac_address(mgp, mgp->dev->dev_addr); - myri10ge_change_promisc(mgp, 0, 0); myri10ge_change_pause(mgp, mgp->pause); - if (mgp->adopted_rx_filter_bug) - (void)myri10ge_send_cmd(mgp, MXGEFW_ENABLE_ALLMULTI, &cmd, 1); + myri10ge_set_multicast_list(mgp->dev); return status; } @@ -2283,7 +2283,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev) myri10ge_change_promisc(mgp, dev->flags & IFF_PROMISC, 1); /* This firmware is known to not support multicast */ - if (!mgp->fw_multicast_support || mgp->adopted_rx_filter_bug) + if (!mgp->fw_multicast_support) return; /* Disable multicast filtering */ @@ -2295,7 +2295,7 @@ static void myri10ge_set_multicast_list(struct net_device *dev) goto abort; } - if (dev->flags & IFF_ALLMULTI) { + if ((dev->flags & IFF_ALLMULTI) || mgp->adopted_rx_filter_bug) { /* request to disable multicast filtering, so quit here */ return; } -- cgit v1.2.3 From 0d6ac257ab556838c3c5b1437a36251c2802285e Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 7 May 2007 23:51:45 +0200 Subject: myri10ge: move the DMA test code into its own function Move the DMA test code into its own function. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 121 ++++++++++++++++++++++------------------ 1 file changed, 68 insertions(+), 53 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index 3245357a06f..f53b0dad65a 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -714,14 +714,78 @@ myri10ge_change_promisc(struct myri10ge_priv *mgp, int promisc, int atomic) mgp->dev->name); } -static int myri10ge_reset(struct myri10ge_priv *mgp) +static int myri10ge_dma_test(struct myri10ge_priv *mgp, int test_type) { struct myri10ge_cmd cmd; int status; - size_t bytes; u32 len; struct page *dmatest_page; dma_addr_t dmatest_bus; + char *test = " "; + + dmatest_page = alloc_page(GFP_KERNEL); + if (!dmatest_page) + return -ENOMEM; + dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE, + DMA_BIDIRECTIONAL); + + /* Run a small DMA test. + * The magic multipliers to the length tell the firmware + * to do DMA read, write, or read+write tests. The + * results are returned in cmd.data0. The upper 16 + * bits or the return is the number of transfers completed. + * The lower 16 bits is the time in 0.5us ticks that the + * transfers took to complete. + */ + + len = mgp->tx.boundary; + + cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); + cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); + cmd.data2 = len * 0x10000; + status = myri10ge_send_cmd(mgp, test_type, &cmd, 0); + if (status != 0) { + test = "read"; + goto abort; + } + mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff); + cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); + cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); + cmd.data2 = len * 0x1; + status = myri10ge_send_cmd(mgp, test_type, &cmd, 0); + if (status != 0) { + test = "write"; + goto abort; + } + mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / (cmd.data0 & 0xffff); + + cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); + cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); + cmd.data2 = len * 0x10001; + status = myri10ge_send_cmd(mgp, test_type, &cmd, 0); + if (status != 0) { + test = "read/write"; + goto abort; + } + mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) / + (cmd.data0 & 0xffff); + +abort: + pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL); + put_page(dmatest_page); + + if (status != 0 && test_type != MXGEFW_CMD_UNALIGNED_TEST) + dev_warn(&mgp->pdev->dev, "DMA %s benchmark failed: %d\n", + test, status); + + return status; +} + +static int myri10ge_reset(struct myri10ge_priv *mgp) +{ + struct myri10ge_cmd cmd; + int status; + size_t bytes; /* try to send a reset command to the card to see if it * is alive */ @@ -731,11 +795,8 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) dev_err(&mgp->pdev->dev, "failed reset\n"); return -ENXIO; } - dmatest_page = alloc_page(GFP_KERNEL); - if (!dmatest_page) - return -ENOMEM; - dmatest_bus = pci_map_page(mgp->pdev, dmatest_page, 0, PAGE_SIZE, - DMA_BIDIRECTIONAL); + + (void)myri10ge_dma_test(mgp, MXGEFW_DMA_TEST); /* Now exchange information about interrupts */ @@ -763,52 +824,6 @@ static int myri10ge_reset(struct myri10ge_priv *mgp) } put_be32(htonl(mgp->intr_coal_delay), mgp->intr_coal_delay_ptr); - /* Run a small DMA test. - * The magic multipliers to the length tell the firmware - * to do DMA read, write, or read+write tests. The - * results are returned in cmd.data0. The upper 16 - * bits or the return is the number of transfers completed. - * The lower 16 bits is the time in 0.5us ticks that the - * transfers took to complete. - */ - - len = mgp->tx.boundary; - - cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); - cmd.data2 = len * 0x10000; - status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); - if (status == 0) - mgp->read_dma = ((cmd.data0 >> 16) * len * 2) / - (cmd.data0 & 0xffff); - else - dev_warn(&mgp->pdev->dev, "DMA read benchmark failed: %d\n", - status); - cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); - cmd.data2 = len * 0x1; - status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); - if (status == 0) - mgp->write_dma = ((cmd.data0 >> 16) * len * 2) / - (cmd.data0 & 0xffff); - else - dev_warn(&mgp->pdev->dev, "DMA write benchmark failed: %d\n", - status); - - cmd.data0 = MYRI10GE_LOWPART_TO_U32(dmatest_bus); - cmd.data1 = MYRI10GE_HIGHPART_TO_U32(dmatest_bus); - cmd.data2 = len * 0x10001; - status = myri10ge_send_cmd(mgp, MXGEFW_DMA_TEST, &cmd, 0); - if (status == 0) - mgp->read_write_dma = ((cmd.data0 >> 16) * len * 2 * 2) / - (cmd.data0 & 0xffff); - else - dev_warn(&mgp->pdev->dev, - "DMA read/write benchmark failed: %d\n", status); - - pci_unmap_page(mgp->pdev, dmatest_bus, PAGE_SIZE, DMA_BIDIRECTIONAL); - put_page(dmatest_page); - memset(mgp->rx_done.entry, 0, bytes); /* reset mcp/driver shared state back to 0 */ -- cgit v1.2.3 From 5443e9ead4f53fd7a43e6846cf10fdc0c5366a93 Mon Sep 17 00:00:00 2001 From: Brice Goglin Date: Mon, 7 May 2007 23:52:22 +0200 Subject: myri10ge: replace the chipset whitelist with firmware autodetection Remove the aligned-completion whitelist, and replace it by using the 1.4.16 firmware's auto-detection features to choose which firmware to load. The driver now loads the aligned firmware, performs a MXGEFW_CMD_UNALIGNED_TEST, and falls back to using the unaligned firmware if: - The firmware is too old (ie, MXGEFW_CMD_UNALIGNED_TEST is an unknown command). - The MXGEFW_CMD_UNALIGNED_TEST returns MXGEFW_CMD_ERROR_UNALIGNED, meaning that it has seen an unaligned completion during the DMA test. Signed-off-by: Brice Goglin Signed-off-by: Jeff Garzik --- drivers/net/myri10ge/myri10ge.c | 121 +++++++++++++++++++++------------------- 1 file changed, 65 insertions(+), 56 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/myri10ge/myri10ge.c b/drivers/net/myri10ge/myri10ge.c index f53b0dad65a..5d14be7405a 100644 --- a/drivers/net/myri10ge/myri10ge.c +++ b/drivers/net/myri10ge/myri10ge.c @@ -355,6 +355,8 @@ myri10ge_send_cmd(struct myri10ge_priv *mgp, u32 cmd, return 0; } else if (result == MXGEFW_CMD_UNKNOWN) { return -ENOSYS; + } else if (result == MXGEFW_CMD_ERROR_UNALIGNED) { + return -E2BIG; } else { dev_err(&mgp->pdev->dev, "command %d failed, result = %d\n", @@ -2483,8 +2485,6 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) err_cap |= PCI_ERR_CAP_ECRC_GENE; pci_write_config_dword(bridge, cap + PCI_ERR_CAP, err_cap); dev_info(dev, "Enabled ECRC on upstream bridge %s\n", pci_name(bridge)); - mgp->tx.boundary = 4096; - mgp->fw_name = myri10ge_fw_aligned; } /* @@ -2506,22 +2506,70 @@ static void myri10ge_enable_ecrc(struct myri10ge_priv *mgp) * firmware image, and set tx.boundary to 4KB. */ -#define PCI_DEVICE_ID_INTEL_E5000_PCIE23 0x25f7 -#define PCI_DEVICE_ID_INTEL_E5000_PCIE47 0x25fa -#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 0x3510 -#define PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4 0x351b -#define PCI_DEVICE_ID_INTEL_E3000_PCIE 0x2779 -#define PCI_DEVICE_ID_INTEL_E3010_PCIE 0x277a -#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST 0x140 -#define PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST 0x142 - -static void myri10ge_select_firmware(struct myri10ge_priv *mgp) +static void myri10ge_firmware_probe(struct myri10ge_priv *mgp) { - struct pci_dev *bridge = mgp->pdev->bus->self; + struct pci_dev *pdev = mgp->pdev; + struct device *dev = &pdev->dev; + int cap, status; + u16 val; + mgp->tx.boundary = 4096; + /* + * Verify the max read request size was set to 4KB + * before trying the test with 4KB. + */ + cap = pci_find_capability(pdev, PCI_CAP_ID_EXP); + if (cap < 64) { + dev_err(dev, "Bad PCI_CAP_ID_EXP location %d\n", cap); + goto abort; + } + status = pci_read_config_word(pdev, cap + PCI_EXP_DEVCTL, &val); + if (status != 0) { + dev_err(dev, "Couldn't read max read req size: %d\n", status); + goto abort; + } + if ((val & (5 << 12)) != (5 << 12)) { + dev_warn(dev, "Max Read Request size != 4096 (0x%x)\n", val); + mgp->tx.boundary = 2048; + } + /* + * load the optimized firmware (which assumes aligned PCIe + * completions) in order to see if it works on this host. + */ + mgp->fw_name = myri10ge_fw_aligned; + status = myri10ge_load_firmware(mgp); + if (status != 0) { + goto abort; + } + + /* + * Enable ECRC if possible + */ + myri10ge_enable_ecrc(mgp); + + /* + * Run a DMA test which watches for unaligned completions and + * aborts on the first one seen. + */ + + status = myri10ge_dma_test(mgp, MXGEFW_CMD_UNALIGNED_TEST); + if (status == 0) + return; /* keep the aligned firmware */ + + if (status != -E2BIG) + dev_warn(dev, "DMA test failed: %d\n", status); + if (status == -ENOSYS) + dev_warn(dev, "Falling back to ethp! " + "Please install up to date fw\n"); +abort: + /* fall back to using the unaligned firmware */ mgp->tx.boundary = 2048; mgp->fw_name = myri10ge_fw_unaligned; +} + +static void myri10ge_select_firmware(struct myri10ge_priv *mgp) +{ if (myri10ge_force_firmware == 0) { int link_width, exp_cap; u16 lnk; @@ -2530,8 +2578,6 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) pci_read_config_word(mgp->pdev, exp_cap + PCI_EXP_LNKSTA, &lnk); link_width = (lnk >> 4) & 0x3f; - myri10ge_enable_ecrc(mgp); - /* Check to see if Link is less than 8 or if the * upstream bridge is known to provide aligned * completions */ @@ -2540,46 +2586,8 @@ static void myri10ge_select_firmware(struct myri10ge_priv *mgp) link_width); mgp->tx.boundary = 4096; mgp->fw_name = myri10ge_fw_aligned; - } else if (bridge && - /* ServerWorks HT2000/HT1000 */ - ((bridge->vendor == PCI_VENDOR_ID_SERVERWORKS - && bridge->device == - PCI_DEVICE_ID_SERVERWORKS_HT2000_PCIE) - /* ServerWorks HT2100 */ - || (bridge->vendor == PCI_VENDOR_ID_SERVERWORKS - && bridge->device >= - PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_FIRST - && bridge->device <= - PCI_DEVICE_ID_SERVERWORKS_HT2100_PCIE_LAST) - /* All Intel E3000/E3010 PCIE ports */ - || (bridge->vendor == PCI_VENDOR_ID_INTEL - && (bridge->device == - PCI_DEVICE_ID_INTEL_E3000_PCIE - || bridge->device == - PCI_DEVICE_ID_INTEL_E3010_PCIE)) - /* All Intel 6310/6311/6321ESB PCIE ports */ - || (bridge->vendor == PCI_VENDOR_ID_INTEL - && bridge->device >= - PCI_DEVICE_ID_INTEL_6300ESB_PCIEE1 - && bridge->device <= - PCI_DEVICE_ID_INTEL_6300ESB_PCIEE4) - /* All Intel E5000 PCIE ports */ - || (bridge->vendor == PCI_VENDOR_ID_INTEL - && bridge->device >= - PCI_DEVICE_ID_INTEL_E5000_PCIE23 - && bridge->device <= - PCI_DEVICE_ID_INTEL_E5000_PCIE47))) { - dev_info(&mgp->pdev->dev, - "Assuming aligned completions (0x%x:0x%x)\n", - bridge->vendor, bridge->device); - mgp->tx.boundary = 4096; - mgp->fw_name = myri10ge_fw_aligned; - } else if (bridge && - bridge->vendor == PCI_VENDOR_ID_SGI && - bridge->device == 0x4002 /* TIOCE pcie-port */ ) { - /* this pcie bridge does not support 4K rdma request */ - mgp->tx.boundary = 2048; - mgp->fw_name = myri10ge_fw_aligned; + } else { + myri10ge_firmware_probe(mgp); } } else { if (myri10ge_force_firmware == 1) { @@ -2847,7 +2855,6 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) status = -ENODEV; goto abort_with_netdev; } - myri10ge_select_firmware(mgp); /* Find the vendor-specific cap so we can check * the reboot register later on */ @@ -2941,6 +2948,8 @@ static int myri10ge_probe(struct pci_dev *pdev, const struct pci_device_id *ent) goto abort_with_ioremap; memset(mgp->rx_done.entry, 0, bytes); + myri10ge_select_firmware(mgp); + status = myri10ge_load_firmware(mgp); if (status != 0) { dev_err(&pdev->dev, "failed to load firmware\n"); -- cgit v1.2.3 From d17ecb23b2e5ca174c0f5ce6be42cb3909a02ed0 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 7 May 2007 11:01:55 -0700 Subject: skge: allow WOL except for known broken chips Wake On Lan works correctly on Yukon-FE and other variants. Signed-off-by: Stephen Hemminger a Signed-off-by: Jeff Garzik --- drivers/net/skge.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/skge.c b/drivers/net/skge.c index 21afe108d3c..b07da1054ad 100644 --- a/drivers/net/skge.c +++ b/drivers/net/skge.c @@ -135,10 +135,13 @@ static void skge_get_regs(struct net_device *dev, struct ethtool_regs *regs, /* Wake on Lan only supported on Yukon chips with rev 1 or above */ static u32 wol_supported(const struct skge_hw *hw) { - if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev != 0) - return WAKE_MAGIC | WAKE_PHY; - else + if (hw->chip_id == CHIP_ID_GENESIS) return 0; + + if (hw->chip_id == CHIP_ID_YUKON && hw->chip_rev == 0) + return 0; + + return WAKE_MAGIC | WAKE_PHY; } static u32 pci_wake_enabled(struct pci_dev *dev) -- cgit v1.2.3 From 9fd9f9b669ca71f7b3a7709d02d305c3d428d2fe Mon Sep 17 00:00:00 2001 From: Ben Dooks Date: Mon, 7 May 2007 11:13:25 +0000 Subject: DM9000: fix use of kfree() on net device The DM9000 network driver is calling kfree() on an netdev causing the system to oops if the probe fails. The right thing to do is call free_netdev(). Thanks to Russell King for spotting this. Signed-off-by: Ben Dooks Signed-off-by: Jeff Garzik --- drivers/net/dm9000.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 8cc1174e7f6..0e338539b82 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -601,7 +601,7 @@ dm9000_probe(struct platform_device *pdev) printk("%s: not found (%d).\n", CARDNAME, ret); dm9000_release_board(pdev, db); - kfree(ndev); + free_netdev(ndev); return ret; } @@ -1193,7 +1193,7 @@ dm9000_drv_remove(struct platform_device *pdev) unregister_netdev(ndev); dm9000_release_board(pdev, (board_info_t *) ndev->priv); - kfree(ndev); /* free device structure */ + free_netdev(ndev); /* free device structure */ PRINTK1("clean_module() exit\n"); -- cgit v1.2.3 From 5125ed914d238cf22783038393ea1e75bc470925 Mon Sep 17 00:00:00 2001 From: Nobuhiro Iwamatsu Date: Thu, 3 May 2007 18:56:56 +0900 Subject: smc91x SuperH support This patch supports SuperH of smc91x. smc91x installed on the board of SuperH comes to work by applying this patch. Please apply this patch . Signed-off-by: Nobuhiro Iwamatsu Signed-off-by: Jeff Garzik --- drivers/net/smc91x.h | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/smc91x.h b/drivers/net/smc91x.h index 7053026d6c7..111f23d0576 100644 --- a/drivers/net/smc91x.h +++ b/drivers/net/smc91x.h @@ -279,6 +279,40 @@ SMC_outw(u16 val, void __iomem *ioaddr, int reg) #define SMC_insw(a, r, p, l) insw((a) + (r), p, l) #define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) +#elif defined(CONFIG_SUPERH) + +#if defined(CONFIG_SH_7780_SOLUTION_ENGINE) || defined(CONFIG_SH_7722_SOLUTION_ENGINE) +#define SMC_CAN_USE_8BIT 0 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 0 +#define SMC_IO_SHIFT 0 +#define SMC_NOWAIT 1 + +#define SMC_inb(a, r) (inw((a) + ((r)&~1)) >> (8*(r%2)))&0xff +#define SMC_inw(a, r) inw((a) + (r)) +#define SMC_outb(v, a, r) outw(((inw((a)+((r)&~1))*(0xff<<8*(r%2)))) | ((v)<<(8*(r&2)))), (a) + ((r)&~1)) + +#define SMC_outw(v, a, r) outw(v, (a) + (r)) +#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) + +#else /* BOARDS */ + +#define SMC_CAN_USE_8BIT 1 +#define SMC_CAN_USE_16BIT 1 +#define SMC_CAN_USE_32BIT 1 + +#define SMC_inb(a, r) inb((a) + (r)) +#define SMC_inw(a, r) inw((a) + (r)) +#define SMC_outb(v, a, r) outb(v, (a) + (r)) +#define SMC_outw(v, a, r) outw(v, (a) + (r)) +#define SMC_insw(a, r, p, l) insw((a) + (r), p, l) +#define SMC_outsw(a, r, p, l) outsw((a) + (r), p, l) + +#endif /* BOARDS */ + +#define set_irq_type(irq, type) do {} while (0) + #elif defined(CONFIG_M32R) #define SMC_CAN_USE_8BIT 0 -- cgit v1.2.3 From d0ed48640e746a5537d0e7c49d5029949b15ee88 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 3 May 2007 10:36:50 +0100 Subject: natsemi: Improve diagnostics for DspCfg workaround The natsemi driver has a workaround for broken hardware which resets itself from time to time. There is a diagnostic message for this workaround but it is not printed by default, making the driver behavior more obscure than it needs to be. Make the message be displayed by default. Signed-Off-By: Mark Brown Signed-off-by: Jeff Garzik --- drivers/net/natsemi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index a8d7ff2c96a..109e8025248 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -1756,7 +1756,7 @@ static void netdev_timer(unsigned long data) if (dspcfg != np->dspcfg) { if (!netif_queue_stopped(dev)) { spin_unlock_irq(&np->lock); - if (netif_msg_hw(np)) + if (netif_msg_drv(np)) printk(KERN_NOTICE "%s: possible phy reset: " "re-initializing\n", dev->name); disable_irq(dev->irq); -- cgit v1.2.3 From 1a14780960888c97371a9918f42c4dbe6957efb4 Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Thu, 3 May 2007 10:36:56 +0100 Subject: Subject: natsemi: Allow users to disable workaround for DspCfg reset The natsemi driver contains a workaround for broken hardware which can partially reset the chip at unpredictable times, detected by checking for spontaneous changes in the DspCfg register. The effects of the hardware bug appear to be variable and can range from minor problems like small numbers of corrupted packets to major ones such as the chip becoming non-functional. In the case of minor problems the chip reconfiguration required to work around the hardware can cause more problems than the bug itself. Since we have no way of automatically determining how badly the problem manifests on any given system provide an option in sysfs allowing users to disable the workaround at runtime and provides a module option to set the default. Signed-Off-By: Mark Brown Signed-off-by: Jeff Garzik --- drivers/net/natsemi.c | 68 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 66 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c index 109e8025248..223e0e6264b 100644 --- a/drivers/net/natsemi.c +++ b/drivers/net/natsemi.c @@ -81,6 +81,8 @@ static const int multicast_filter_limit = 100; Setting to > 1518 effectively disables this feature. */ static int rx_copybreak; +static int dspcfg_workaround = 1; + /* Used to pass the media type, etc. Both 'options[]' and 'full_duplex[]' should exist for driver interoperability. @@ -139,12 +141,14 @@ MODULE_LICENSE("GPL"); module_param(mtu, int, 0); module_param(debug, int, 0); module_param(rx_copybreak, int, 0); +module_param(dspcfg_workaround, int, 1); module_param_array(options, int, NULL, 0); module_param_array(full_duplex, int, NULL, 0); MODULE_PARM_DESC(mtu, "DP8381x MTU (all boards)"); MODULE_PARM_DESC(debug, "DP8381x default debug level"); MODULE_PARM_DESC(rx_copybreak, "DP8381x copy breakpoint for copy-only-tiny-frames"); +MODULE_PARM_DESC(dspcfg_workaround, "DP8381x: control DspCfg workaround"); MODULE_PARM_DESC(options, "DP8381x: Bits 0-3: media type, bit 17: full duplex"); MODULE_PARM_DESC(full_duplex, "DP8381x full duplex setting(s) (1)"); @@ -590,6 +594,7 @@ struct netdev_private { u32 srr; /* expected DSPCFG value */ u16 dspcfg; + int dspcfg_workaround; /* parms saved in ethtool format */ u16 speed; /* The forced speed, 10Mb, 100Mb, gigabit */ u8 duplex; /* Duplex, half or full */ @@ -656,6 +661,56 @@ static int netdev_get_regs(struct net_device *dev, u8 *buf); static int netdev_get_eeprom(struct net_device *dev, u8 *buf); static const struct ethtool_ops ethtool_ops; +#define NATSEMI_ATTR(_name) \ +static ssize_t natsemi_show_##_name(struct device *dev, \ + struct device_attribute *attr, char *buf); \ + static ssize_t natsemi_set_##_name(struct device *dev, \ + struct device_attribute *attr, \ + const char *buf, size_t count); \ + static DEVICE_ATTR(_name, 0644, natsemi_show_##_name, natsemi_set_##_name) + +#define NATSEMI_CREATE_FILE(_dev, _name) \ + device_create_file(&_dev->dev, &dev_attr_##_name) +#define NATSEMI_REMOVE_FILE(_dev, _name) \ + device_create_file(&_dev->dev, &dev_attr_##_name) + +NATSEMI_ATTR(dspcfg_workaround); + +static ssize_t natsemi_show_dspcfg_workaround(struct device *dev, + struct device_attribute *attr, + char *buf) +{ + struct netdev_private *np = netdev_priv(to_net_dev(dev)); + + return sprintf(buf, "%s\n", np->dspcfg_workaround ? "on" : "off"); +} + +static ssize_t natsemi_set_dspcfg_workaround(struct device *dev, + struct device_attribute *attr, + const char *buf, size_t count) +{ + struct netdev_private *np = netdev_priv(to_net_dev(dev)); + int new_setting; + u32 flags; + + /* Find out the new setting */ + if (!strncmp("on", buf, count - 1) || !strncmp("1", buf, count - 1)) + new_setting = 1; + else if (!strncmp("off", buf, count - 1) + || !strncmp("0", buf, count - 1)) + new_setting = 0; + else + return count; + + spin_lock_irqsave(&np->lock, flags); + + np->dspcfg_workaround = new_setting; + + spin_unlock_irqrestore(&np->lock, flags); + + return count; +} + static inline void __iomem *ns_ioaddr(struct net_device *dev) { return (void __iomem *) dev->base_addr; @@ -820,6 +875,7 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, np->ignore_phy = 1; else np->ignore_phy = 0; + np->dspcfg_workaround = dspcfg_workaround; /* Initial port: * - If configured to ignore the PHY set up for external. @@ -899,6 +955,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, if (i) goto err_register_netdev; + if (NATSEMI_CREATE_FILE(pdev, dspcfg_workaround)) + goto err_create_file; + if (netif_msg_drv(np)) { printk(KERN_INFO "natsemi %s: %s at %#08lx (%s), ", dev->name, natsemi_pci_info[chip_idx].name, iostart, @@ -915,6 +974,9 @@ static int __devinit natsemi_probe1 (struct pci_dev *pdev, } return 0; + err_create_file: + unregister_netdev(dev); + err_register_netdev: iounmap(ioaddr); @@ -1727,7 +1789,8 @@ static void init_registers(struct net_device *dev) * It seems that a reference set for this chip went out with incorrect info, * and there exist boards that aren't quite right. An unexpected voltage * drop can cause the PHY to get itself in a weird state (basically reset). - * NOTE: this only seems to affect revC chips. + * NOTE: this only seems to affect revC chips. The user can disable + * this check via dspcfg_workaround sysfs option. * 3) check of death of the RX path due to OOM */ static void netdev_timer(unsigned long data) @@ -1753,7 +1816,7 @@ static void netdev_timer(unsigned long data) writew(1, ioaddr+PGSEL); dspcfg = readw(ioaddr+DSPCFG); writew(0, ioaddr+PGSEL); - if (dspcfg != np->dspcfg) { + if (np->dspcfg_workaround && dspcfg != np->dspcfg) { if (!netif_queue_stopped(dev)) { spin_unlock_irq(&np->lock); if (netif_msg_drv(np)) @@ -3157,6 +3220,7 @@ static void __devexit natsemi_remove1 (struct pci_dev *pdev) struct net_device *dev = pci_get_drvdata(pdev); void __iomem * ioaddr = ns_ioaddr(dev); + NATSEMI_REMOVE_FILE(pdev, dspcfg_workaround); unregister_netdev (dev); pci_release_regions (pdev); iounmap(ioaddr); -- cgit v1.2.3 From 88ca2d070c3a169611ec38f00e945a036564ca26 Mon Sep 17 00:00:00 2001 From: Thomas Klein Date: Wed, 2 May 2007 16:07:05 +0200 Subject: ehea: Fix skb header access Adapt to new skb header access functions. Signed-off-by: Thomas Klein Signed-off-by: Jeff Garzik --- drivers/net/ehea/ehea_main.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ehea/ehea_main.c b/drivers/net/ehea/ehea_main.c index c7a5614e66c..721164874a8 100644 --- a/drivers/net/ehea/ehea_main.c +++ b/drivers/net/ehea/ehea_main.c @@ -1803,10 +1803,10 @@ static inline int ehea_hash_skb(struct sk_buff *skb, int num_qps) u32 tmp; if ((skb->protocol == htons(ETH_P_IP)) && - (skb->nh.iph->protocol == IPPROTO_TCP)) { - tcp = (struct tcphdr*)(skb->nh.raw + (skb->nh.iph->ihl * 4)); + (ip_hdr(skb)->protocol == IPPROTO_TCP)) { + tcp = (struct tcphdr*)(skb_network_header(skb) + (ip_hdr(skb)->ihl * 4)); tmp = (tcp->source + (tcp->dest << 16)) % 31; - tmp += skb->nh.iph->daddr % 31; + tmp += ip_hdr(skb)->daddr % 31; return tmp % num_qps; } else -- cgit v1.2.3 From 1e0063645ef1e89c63778fbb0417e79b7dc65b5f Mon Sep 17 00:00:00 2001 From: Jay Cliburn Date: Sun, 29 Apr 2007 21:42:10 -0500 Subject: atl1: use dev_printk macros Use dev_printk macros for PCI related errors, warnings, debug and info console messages. Signed-off-by: Jay Cliburn Signed-off-by: Jeff Garzik --- drivers/net/atl1/atl1_ethtool.c | 19 ++++------ drivers/net/atl1/atl1_hw.c | 22 +++++------ drivers/net/atl1/atl1_main.c | 83 ++++++++++++++++++----------------------- drivers/net/atl1/atl1_param.c | 31 +++++++-------- 4 files changed, 68 insertions(+), 87 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atl1/atl1_ethtool.c b/drivers/net/atl1/atl1_ethtool.c index c11c27798e5..1f616c5c147 100644 --- a/drivers/net/atl1/atl1_ethtool.c +++ b/drivers/net/atl1/atl1_ethtool.c @@ -156,8 +156,7 @@ static int atl1_set_settings(struct net_device *netdev, u16 old_media_type = hw->media_type; if (netif_running(adapter->netdev)) { - printk(KERN_DEBUG "%s: ethtool shutting down adapter\n", - atl1_driver_name); + dev_dbg(&adapter->pdev->dev, "ethtool shutting down adapter\n"); atl1_down(adapter); } @@ -166,9 +165,8 @@ static int atl1_set_settings(struct net_device *netdev, else { if (ecmd->speed == SPEED_1000) { if (ecmd->duplex != DUPLEX_FULL) { - printk(KERN_WARNING - "%s: can't force to 1000M half duplex\n", - atl1_driver_name); + dev_warn(&adapter->pdev->dev, + "can't force to 1000M half duplex\n"); ret_val = -EINVAL; goto exit_sset; } @@ -206,9 +204,8 @@ static int atl1_set_settings(struct net_device *netdev, } if (atl1_phy_setup_autoneg_adv(hw)) { ret_val = -EINVAL; - printk(KERN_WARNING - "%s: invalid ethtool speed/duplex setting\n", - atl1_driver_name); + dev_warn(&adapter->pdev->dev, + "invalid ethtool speed/duplex setting\n"); goto exit_sset; } if (hw->media_type == MEDIA_TYPE_AUTO_SENSOR || @@ -239,12 +236,10 @@ exit_sset: hw->media_type = old_media_type; if (netif_running(adapter->netdev)) { - printk(KERN_DEBUG "%s: ethtool starting adapter\n", - atl1_driver_name); + dev_dbg(&adapter->pdev->dev, "ethtool starting adapter\n"); atl1_up(adapter); } else if (!ret_val) { - printk(KERN_DEBUG "%s: ethtool resetting adapter\n", - atl1_driver_name); + dev_dbg(&adapter->pdev->dev, "ethtool resetting adapter\n"); atl1_reset(adapter); } return ret_val; diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c index 69482e0d849..5b9dd3c1e84 100644 --- a/drivers/net/atl1/atl1_hw.c +++ b/drivers/net/atl1/atl1_hw.c @@ -38,6 +38,7 @@ */ s32 atl1_reset_hw(struct atl1_hw *hw) { + struct pci_dev *pdev = hw->back->pdev; u32 icr; int i; @@ -74,7 +75,7 @@ s32 atl1_reset_hw(struct atl1_hw *hw) } if (icr) { - printk (KERN_DEBUG "icr = %x\n", icr); + dev_dbg(&pdev->dev, "ICR = 0x%x\n", icr); return icr; } @@ -437,6 +438,7 @@ s32 atl1_phy_enter_power_saving(struct atl1_hw *hw) */ static s32 atl1_phy_reset(struct atl1_hw *hw) { + struct pci_dev *pdev = hw->back->pdev; s32 ret_val; u16 phy_data; @@ -468,8 +470,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw) u32 val; int i; /* pcie serdes link may be down! */ - printk(KERN_DEBUG "%s: autoneg caused pcie phy link down\n", - atl1_driver_name); + dev_dbg(&pdev->dev, "pcie phy link down\n"); for (i = 0; i < 25; i++) { msleep(1); @@ -479,9 +480,7 @@ static s32 atl1_phy_reset(struct atl1_hw *hw) } if ((val & (MDIO_START | MDIO_BUSY)) != 0) { - printk(KERN_WARNING - "%s: pcie link down at least for 25ms\n", - atl1_driver_name); + dev_warn(&pdev->dev, "pcie link down at least 25ms\n"); return ret_val; } } @@ -571,6 +570,7 @@ s32 atl1_phy_setup_autoneg_adv(struct atl1_hw *hw) */ static s32 atl1_setup_link(struct atl1_hw *hw) { + struct pci_dev *pdev = hw->back->pdev; s32 ret_val; /* @@ -581,15 +581,13 @@ static s32 atl1_setup_link(struct atl1_hw *hw) */ ret_val = atl1_phy_setup_autoneg_adv(hw); if (ret_val) { - printk(KERN_DEBUG "%s: error setting up autonegotiation\n", - atl1_driver_name); + dev_dbg(&pdev->dev, "error setting up autonegotiation\n"); return ret_val; } /* SW.Reset , En-Auto-Neg if needed */ ret_val = atl1_phy_reset(hw); if (ret_val) { - printk(KERN_DEBUG "%s: error resetting the phy\n", - atl1_driver_name); + dev_dbg(&pdev->dev, "error resetting phy\n"); return ret_val; } hw->phy_configured = true; @@ -669,6 +667,7 @@ s32 atl1_init_hw(struct atl1_hw *hw) */ s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex) { + struct pci_dev *pdev = hw->back->pdev; s32 ret_val; u16 phy_data; @@ -691,8 +690,7 @@ s32 atl1_get_speed_and_duplex(struct atl1_hw *hw, u16 *speed, u16 *duplex) *speed = SPEED_10; break; default: - printk(KERN_DEBUG "%s: error getting speed\n", - atl1_driver_name); + dev_dbg(&pdev->dev, "error getting speed\n"); return ATL1_ERR_PHY_SPEED; break; } diff --git a/drivers/net/atl1/atl1_main.c b/drivers/net/atl1/atl1_main.c index 4b1d4d153ec..d28f88bbdd5 100644 --- a/drivers/net/atl1/atl1_main.c +++ b/drivers/net/atl1/atl1_main.c @@ -188,8 +188,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) size = sizeof(struct atl1_buffer) * (tpd_ring->count + rfd_ring->count); tpd_ring->buffer_info = kzalloc(size, GFP_KERNEL); if (unlikely(!tpd_ring->buffer_info)) { - printk(KERN_WARNING "%s: kzalloc failed , size = D%d\n", - atl1_driver_name, size); + dev_err(&pdev->dev, "kzalloc failed , size = D%d\n", size); goto err_nomem; } rfd_ring->buffer_info = @@ -207,9 +206,7 @@ s32 atl1_setup_ring_resources(struct atl1_adapter *adapter) ring_header->desc = pci_alloc_consistent(pdev, ring_header->size, &ring_header->dma); if (unlikely(!ring_header->desc)) { - printk(KERN_WARNING - "%s: pci_alloc_consistent failed, size = D%d\n", - atl1_driver_name, size); + dev_err(&pdev->dev, "pci_alloc_consistent failed\n"); goto err_nomem; } @@ -373,8 +370,7 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter, if (rrd->err_flg & (ERR_FLAG_CRC | ERR_FLAG_TRUNC | ERR_FLAG_CODE | ERR_FLAG_OV)) { adapter->hw_csum_err++; - printk(KERN_DEBUG "%s: rx checksum error\n", - atl1_driver_name); + dev_dbg(&adapter->pdev->dev, "rx checksum error\n"); return; } } @@ -393,8 +389,9 @@ static void atl1_rx_checksum(struct atl1_adapter *adapter, } /* IPv4, but hardware thinks its checksum is wrong */ - printk(KERN_DEBUG "%s: hw csum wrong pkt_flag:%x, err_flag:%x\n", - atl1_driver_name, rrd->pkt_flg, rrd->err_flg); + dev_dbg(&adapter->pdev->dev, + "hw csum wrong, pkt_flag:%x, err_flag:%x\n", + rrd->pkt_flg, rrd->err_flg); skb->ip_summed = CHECKSUM_COMPLETE; skb->csum = htons(rrd->xsz.xsum_sz.rx_chksum); adapter->hw_csum_err++; @@ -507,14 +504,13 @@ chk_rrd: /* rrd seems to be bad */ if (unlikely(i-- > 0)) { /* rrd may not be DMAed completely */ - printk(KERN_DEBUG - "%s: RRD may not be DMAed completely\n", - atl1_driver_name); + dev_dbg(&adapter->pdev->dev, + "incomplete RRD DMA transfer\n"); udelay(1); goto chk_rrd; } /* bad rrd */ - printk(KERN_DEBUG "%s: bad RRD\n", atl1_driver_name); + dev_dbg(&adapter->pdev->dev, "bad RRD\n"); /* see if update RFD index */ if (rrd->num_buf > 1) { u16 num_buf; @@ -685,8 +681,8 @@ static void atl1_check_for_link(struct atl1_adapter *adapter) /* notify upper layer link down ASAP */ if (!(phy_data & BMSR_LSTATUS)) { /* Link Down */ if (netif_carrier_ok(netdev)) { /* old link state: Up */ - printk(KERN_INFO "%s: %s link is down\n", - atl1_driver_name, netdev->name); + dev_info(&adapter->pdev->dev, "%s link is down\n", + netdev->name); adapter->link_speed = SPEED_0; netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -731,8 +727,8 @@ static irqreturn_t atl1_intr(int irq, void *data) /* check if PCIE PHY Link down */ if (status & ISR_PHY_LINKDOWN) { - printk(KERN_DEBUG "%s: pcie phy link down %x\n", - atl1_driver_name, status); + dev_dbg(&adapter->pdev->dev, "pcie phy link down %x\n", + status); if (netif_running(adapter->netdev)) { /* reset MAC */ iowrite32(0, adapter->hw.hw_addr + REG_IMR); schedule_work(&adapter->pcie_dma_to_rst_task); @@ -742,9 +738,9 @@ static irqreturn_t atl1_intr(int irq, void *data) /* check if DMA read/write error ? */ if (status & (ISR_DMAR_TO_RST | ISR_DMAW_TO_RST)) { - printk(KERN_DEBUG - "%s: pcie DMA r/w error (status = 0x%x)\n", - atl1_driver_name, status); + dev_dbg(&adapter->pdev->dev, + "pcie DMA r/w error (status = 0x%x)\n", + status); iowrite32(0, adapter->hw.hw_addr + REG_IMR); schedule_work(&adapter->pcie_dma_to_rst_task); return IRQ_HANDLED; @@ -762,14 +758,13 @@ static irqreturn_t atl1_intr(int irq, void *data) /* rx exception */ if (unlikely(status & (ISR_RXF_OV | ISR_RFD_UNRUN | + ISR_RRD_OV | ISR_HOST_RFD_UNRUN | + ISR_HOST_RRD_OV | ISR_CMB_RX))) { + if (status & (ISR_RXF_OV | ISR_RFD_UNRUN | ISR_RRD_OV | ISR_HOST_RFD_UNRUN | - ISR_HOST_RRD_OV | ISR_CMB_RX))) { - if (status & - (ISR_RXF_OV | ISR_RFD_UNRUN | ISR_RRD_OV | - ISR_HOST_RFD_UNRUN | ISR_HOST_RRD_OV)) - printk(KERN_INFO - "%s: rx exception: status = 0x%x\n", - atl1_driver_name, status); + ISR_HOST_RRD_OV)) + dev_dbg(&adapter->pdev->dev, + "rx exception, ISR = 0x%x\n", status); atl1_intr_rx(adapter); } @@ -874,8 +869,7 @@ static u32 atl1_check_link(struct atl1_adapter *adapter) atl1_read_phy_reg(hw, MII_BMSR, &phy_data); if (!(phy_data & BMSR_LSTATUS)) { /* link down */ if (netif_carrier_ok(netdev)) { /* old link state: Up */ - printk(KERN_INFO "%s: link is down\n", - atl1_driver_name); + dev_info(&adapter->pdev->dev, "link is down\n"); adapter->link_speed = SPEED_0; netif_carrier_off(netdev); netif_stop_queue(netdev); @@ -918,11 +912,11 @@ static u32 atl1_check_link(struct atl1_adapter *adapter) adapter->link_speed = speed; adapter->link_duplex = duplex; atl1_setup_mac_ctrl(adapter); - printk(KERN_INFO "%s: %s link is up %d Mbps %s\n", - atl1_driver_name, netdev->name, - adapter->link_speed, - adapter->link_duplex == - FULL_DUPLEX ? "full duplex" : "half duplex"); + dev_info(&adapter->pdev->dev, + "%s link is up %d Mbps %s\n", + netdev->name, adapter->link_speed, + adapter->link_duplex == FULL_DUPLEX ? + "full duplex" : "half duplex"); } if (!netif_carrier_ok(netdev)) { /* Link down -> Up */ netif_carrier_on(netdev); @@ -1330,8 +1324,8 @@ static int atl1_tx_csum(struct atl1_adapter *adapter, struct sk_buff *skb, cso = skb_transport_offset(skb); css = cso + skb->csum_offset; if (unlikely(cso & 0x1)) { - printk(KERN_DEBUG "%s: payload offset != even number\n", - atl1_driver_name); + dev_dbg(&adapter->pdev->dev, + "payload offset not an even number\n"); return -1; } csum->csumpl |= (cso & CSUM_PARAM_PLOADOFFSET_MASK) << @@ -1579,7 +1573,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) if (!spin_trylock(&adapter->lock)) { /* Can't get lock - tell upper layer to requeue */ local_irq_restore(flags); - printk(KERN_DEBUG "%s: TX locked\n", atl1_driver_name); + dev_dbg(&adapter->pdev->dev, "tx locked\n"); return NETDEV_TX_LOCKED; } @@ -1587,7 +1581,7 @@ static int atl1_xmit_frame(struct sk_buff *skb, struct net_device *netdev) /* not enough descriptors */ netif_stop_queue(netdev); spin_unlock_irqrestore(&adapter->lock, flags); - printk(KERN_DEBUG "%s: TX busy\n", atl1_driver_name); + dev_dbg(&adapter->pdev->dev, "tx busy\n"); return NETDEV_TX_BUSY; } @@ -1841,8 +1835,7 @@ static int atl1_change_mtu(struct net_device *netdev, int new_mtu) if ((max_frame < MINIMUM_ETHERNET_FRAME_SIZE) || (max_frame > MAX_JUMBO_FRAME_SIZE)) { - printk(KERN_WARNING "%s: invalid MTU setting\n", - atl1_driver_name); + dev_warn(&adapter->pdev->dev, "invalid MTU setting\n"); return -EINVAL; } @@ -2136,9 +2129,7 @@ static int __devinit atl1_probe(struct pci_dev *pdev, if (err) { err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); if (err) { - printk(KERN_DEBUG - "%s: no usable DMA configuration, aborting\n", - atl1_driver_name); + dev_err(&pdev->dev, "no usable DMA configuration\n"); goto err_dma; } pci_using_64 = false; @@ -2175,7 +2166,9 @@ static int __devinit atl1_probe(struct pci_dev *pdev, goto err_pci_iomap; } /* get device revision number */ - adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + (REG_MASTER_CTRL + 2)); + adapter->hw.dev_rev = ioread16(adapter->hw.hw_addr + + (REG_MASTER_CTRL + 2)); + dev_info(&pdev->dev, "version %s\n", DRIVER_VERSION); /* set default ring resource counts */ adapter->rfd_ring.count = adapter->rrd_ring.count = ATL1_DEFAULT_RFD; @@ -2466,8 +2459,6 @@ static void __exit atl1_exit_module(void) */ static int __init atl1_init_module(void) { - printk(KERN_INFO "%s - version %s\n", atl1_driver_string, DRIVER_VERSION); - printk(KERN_INFO "%s\n", atl1_copyright); return pci_register_driver(&atl1_driver); } diff --git a/drivers/net/atl1/atl1_param.c b/drivers/net/atl1/atl1_param.c index bcd0bd89172..324f9f0ece9 100644 --- a/drivers/net/atl1/atl1_param.c +++ b/drivers/net/atl1/atl1_param.c @@ -93,7 +93,7 @@ struct atl1_option { } arg; }; -static int __devinit atl1_validate_option(int *value, struct atl1_option *opt) +static int __devinit atl1_validate_option(int *value, struct atl1_option *opt, struct pci_dev *pdev) { if (*value == OPTION_UNSET) { *value = opt->def; @@ -104,19 +104,17 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt) case enable_option: switch (*value) { case OPTION_ENABLED: - printk(KERN_INFO "%s: %s Enabled\n", atl1_driver_name, - opt->name); + dev_info(&pdev->dev, "%s enabled\n", opt->name); return 0; case OPTION_DISABLED: - printk(KERN_INFO "%s: %s Disabled\n", atl1_driver_name, - opt->name); + dev_info(&pdev->dev, "%s disabled\n", opt->name); return 0; } break; case range_option: if (*value >= opt->arg.r.min && *value <= opt->arg.r.max) { - printk(KERN_INFO "%s: %s set to %i\n", - atl1_driver_name, opt->name, *value); + dev_info(&pdev->dev, "%s set to %i\n", opt->name, + *value); return 0; } break; @@ -128,8 +126,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt) ent = &opt->arg.l.p[i]; if (*value == ent->i) { if (ent->str[0] != '\0') - printk(KERN_INFO "%s: %s\n", - atl1_driver_name, ent->str); + dev_info(&pdev->dev, "%s\n", + ent->str); return 0; } } @@ -140,8 +138,8 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt) break; } - printk(KERN_INFO "%s: invalid %s specified (%i) %s\n", - atl1_driver_name, opt->name, *value, opt->err); + dev_info(&pdev->dev, "invalid %s specified (%i) %s\n", + opt->name, *value, opt->err); *value = opt->def; return -1; } @@ -157,12 +155,11 @@ static int __devinit atl1_validate_option(int *value, struct atl1_option *opt) */ void __devinit atl1_check_options(struct atl1_adapter *adapter) { + struct pci_dev *pdev = adapter->pdev; int bd = adapter->bd_number; if (bd >= ATL1_MAX_NIC) { - printk(KERN_NOTICE "%s: warning: no configuration for board #%i\n", - atl1_driver_name, bd); - printk(KERN_NOTICE "%s: using defaults for all values\n", - atl1_driver_name); + dev_notice(&pdev->dev, "no configuration for board#%i\n", bd); + dev_notice(&pdev->dev, "using defaults for all values\n"); } { /* Interrupt Moderate Timer */ struct atl1_option opt = { @@ -177,7 +174,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter) int val; if (num_int_mod_timer > bd) { val = int_mod_timer[bd]; - atl1_validate_option(&val, &opt); + atl1_validate_option(&val, &opt, pdev); adapter->imt = (u16) val; } else adapter->imt = (u16) (opt.def); @@ -197,7 +194,7 @@ void __devinit atl1_check_options(struct atl1_adapter *adapter) int val; if (num_flash_vendor > bd) { val = flash_vendor[bd]; - atl1_validate_option(&val, &opt); + atl1_validate_option(&val, &opt, pdev); adapter->hw.flash_vendor = (u8) val; } else adapter->hw.flash_vendor = (u8) (opt.def); -- cgit v1.2.3 From ab13a18a3c8cc5a386ae8c74d53ed5ca0b0ec7bb Mon Sep 17 00:00:00 2001 From: Jay Cliburn Date: Sun, 29 Apr 2007 21:42:11 -0500 Subject: atl1: fix whitespace damage Remove trailing whitespace and spaces preceding tabs. Signed-off-by: Jay Cliburn Signed-off-by: Jeff Garzik --- drivers/net/atl1/atl1_hw.c | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/atl1/atl1_hw.c b/drivers/net/atl1/atl1_hw.c index 5b9dd3c1e84..ef886bdeac1 100644 --- a/drivers/net/atl1/atl1_hw.c +++ b/drivers/net/atl1/atl1_hw.c @@ -2,20 +2,20 @@ * Copyright(c) 2005 - 2006 Attansic Corporation. All rights reserved. * Copyright(c) 2006 Chris Snook * Copyright(c) 2006 Jay Cliburn - * + * * Derived from Intel e1000 driver * Copyright(c) 1999 - 2005 Intel Corporation. All rights reserved. - * + * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the Free * Software Foundation; either version 2 of the License, or (at your option) * 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. @@ -42,9 +42,9 @@ s32 atl1_reset_hw(struct atl1_hw *hw) u32 icr; int i; - /* + /* * Clear Interrupt mask to stop board from generating - * interrupts & Clear any pending interrupt events + * interrupts & Clear any pending interrupt events */ /* * iowrite32(0, hw->hw_addr + REG_IMR); @@ -137,8 +137,8 @@ s32 atl1_read_phy_reg(struct atl1_hw *hw, u16 reg_addr, u16 *phy_data) int i; val = ((u32) (reg_addr & MDIO_REG_ADDR_MASK)) << MDIO_REG_ADDR_SHIFT | - MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 << - MDIO_CLK_SEL_SHIFT; + MDIO_START | MDIO_SUP_PREAMBLE | MDIO_RW | MDIO_CLK_25_4 << + MDIO_CLK_SEL_SHIFT; iowrite32(val, hw->hw_addr + REG_MDIO_CTRL); ioread32(hw->hw_addr + REG_MDIO_CTRL); @@ -205,7 +205,7 @@ static bool atl1_spi_read(struct atl1_hw *hw, u32 addr, u32 *buf) /* * get_permanent_address - * return 0 if get valid mac address, + * return 0 if get valid mac address, */ static int atl1_get_permanent_address(struct atl1_hw *hw) { @@ -302,7 +302,7 @@ static int atl1_get_permanent_address(struct atl1_hw *hw) } /* - * Reads the adapter's MAC address from the EEPROM + * Reads the adapter's MAC address from the EEPROM * hw - Struct containing variables accessed by shared code */ s32 atl1_read_mac_addr(struct atl1_hw *hw) @@ -629,7 +629,7 @@ static void atl1_init_flash_opcode(struct atl1_hw *hw) * Performs basic configuration of the adapter. * hw - Struct containing variables accessed by shared code * Assumes that the controller has previously been reset and is in a - * post-reset uninitialized state. Initializes multicast table, + * post-reset uninitialized state. Initializes multicast table, * and Calls routines to setup link * Leaves the transmit and receive units disabled and uninitialized. */ -- cgit v1.2.3 From 42b1c8cc25f6a5ecbd43f9d66e8b8b7ec25b7d9d Mon Sep 17 00:00:00 2001 From: "John W. Linville" Date: Sat, 28 Apr 2007 20:28:45 -0400 Subject: libertas: fix for wireless Kconfig changes Need to change the libertas Kconfig entry to match changes made for other wireless drivers. Signed-off-by: John W. Linville Signed-off-by: Jeff Garzik --- drivers/net/wireless/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/wireless/Kconfig b/drivers/net/wireless/Kconfig index 0184614517f..e273347dc60 100644 --- a/drivers/net/wireless/Kconfig +++ b/drivers/net/wireless/Kconfig @@ -267,7 +267,7 @@ config IPW2200_DEBUG config LIBERTAS_USB tristate "Marvell Libertas 8388 802.11a/b/g cards" - depends on NET_RADIO && USB + depends on USB && WLAN_80211 select FW_LOADER ---help--- A driver for Marvell Libertas 8388 USB devices. -- cgit v1.2.3 From a4d542b9fcae220a067156927e29a34cba605339 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 1 May 2007 00:27:31 +0900 Subject: ne: Add platform_driver Add a platform_driver interface to ne driver. (Existing legacy ports did not covered by this ne_driver for now) Signed-off-by: Atsushi Nemoto Signed-off-by: Jeff Garzik --- drivers/net/ne.c | 91 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 89 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ne.c b/drivers/net/ne.c index a5c4199e275..aef470d6b9a 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -51,6 +51,7 @@ static const char version2[] = #include #include #include +#include #include #include @@ -807,6 +808,87 @@ retry: return; } +static int __init ne_drv_probe(struct platform_device *pdev) +{ + struct net_device *dev; + struct resource *res; + int err, irq; + + res = platform_get_resource(pdev, IORESOURCE_IO, 0); + irq = platform_get_irq(pdev, 0); + if (!res || irq < 0) + return -ENODEV; + + dev = alloc_ei_netdev(); + if (!dev) + return -ENOMEM; + dev->irq = irq; + dev->base_addr = res->start; + err = do_ne_probe(dev); + if (err) { + free_netdev(dev); + return err; + } + platform_set_drvdata(pdev, dev); + return 0; +} + +static int __exit ne_drv_remove(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + + unregister_netdev(dev); + free_irq(dev->irq, dev); + release_region(dev->base_addr, NE_IO_EXTENT); + free_netdev(dev); + return 0; +} + +#ifdef CONFIG_PM +static int ne_drv_suspend(struct platform_device *pdev, pm_message_t state) +{ + struct net_device *dev = platform_get_drvdata(pdev); + + if (netif_running(dev)) + netif_device_detach(dev); + return 0; +} + +static int ne_drv_resume(struct platform_device *pdev) +{ + struct net_device *dev = platform_get_drvdata(pdev); + + if (netif_running(dev)) { + ne_reset_8390(dev); + NS8390_init(dev, 1); + netif_device_attach(dev); + } + return 0; +} +#else +#define ne_drv_suspend NULL +#define ne_drv_resume NULL +#endif + +static struct platform_driver ne_driver = { + .remove = __exit_p(ne_drv_remove), + .suspend = ne_drv_suspend, + .resume = ne_drv_resume, + .driver = { + .name = DRV_NAME, + .owner = THIS_MODULE, + }, +}; + +static int __init ne_init(void) +{ + return platform_driver_probe(&ne_driver, ne_drv_probe); +} + +static void __exit ne_exit(void) +{ + platform_driver_unregister(&ne_driver); +} #ifdef MODULE #define MAX_NE_CARDS 4 /* Max number of NE cards per module */ @@ -832,6 +914,7 @@ ISA device autoprobes on a running machine are not recommended anyway. */ int __init init_module(void) { int this_dev, found = 0; + int plat_found = !ne_init(); for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { struct net_device *dev = alloc_ei_netdev(); @@ -845,7 +928,7 @@ int __init init_module(void) continue; } free_netdev(dev); - if (found) + if (found || plat_found) break; if (io[this_dev] != 0) printk(KERN_WARNING "ne.c: No NE*000 card found at i/o = %#x\n", io[this_dev]); @@ -853,7 +936,7 @@ int __init init_module(void) printk(KERN_NOTICE "ne.c: You must supply \"io=0xNNN\" value(s) for ISA cards.\n"); return -ENXIO; } - if (found) + if (found || plat_found) return 0; return -ENODEV; } @@ -871,6 +954,7 @@ void __exit cleanup_module(void) { int this_dev; + ne_exit(); for (this_dev = 0; this_dev < MAX_NE_CARDS; this_dev++) { struct net_device *dev = dev_ne[this_dev]; if (dev) { @@ -880,4 +964,7 @@ void __exit cleanup_module(void) } } } +#else /* MODULE */ +module_init(ne_init); +module_exit(ne_exit); #endif /* MODULE */ -- cgit v1.2.3 From f0e93c10faf08e8840a0b7a44abccb520ead12df Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 1 May 2007 00:27:39 +0900 Subject: ne: Misc fixes for platform driver. Miscellaneous fixes to make ne platform driver work properly. * Make ioaddr 'unsigned long'. * Move a printk down to show dev->name assigned in register_netdev. Signed-off-by: Atsushi Nemoto Signed-off-by: Jeff Garzik --- drivers/net/ne.c | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ne.c b/drivers/net/ne.c index aef470d6b9a..32ae91b0b61 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -147,7 +147,7 @@ bad_clone_list[] __initdata = { # define DCR_VAL 0x49 #endif -static int ne_probe1(struct net_device *dev, int ioaddr); +static int ne_probe1(struct net_device *dev, unsigned long ioaddr); static int ne_probe_isapnp(struct net_device *dev); static int ne_open(struct net_device *dev); @@ -185,7 +185,7 @@ static void ne_block_output(struct net_device *dev, const int count, static int __init do_ne_probe(struct net_device *dev) { - unsigned int base_addr = dev->base_addr; + unsigned long base_addr = dev->base_addr; #ifndef MODULE int orig_irq = dev->irq; #endif @@ -286,7 +286,7 @@ static int __init ne_probe_isapnp(struct net_device *dev) return -ENODEV; } -static int __init ne_probe1(struct net_device *dev, int ioaddr) +static int __init ne_probe1(struct net_device *dev, unsigned long ioaddr) { int i; unsigned char SA_prom[32]; @@ -325,7 +325,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) if (ei_debug && version_printed++ == 0) printk(KERN_INFO "%s" KERN_INFO "%s", version1, version2); - printk(KERN_INFO "NE*000 ethercard probe at %#3x:", ioaddr); + printk(KERN_INFO "NE*000 ethercard probe at %#3lx:", ioaddr); /* A user with a poor card that fails to ack the reset, or that does not have a valid 0x57,0x57 signature can still use this @@ -517,8 +517,7 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) } #endif - printk("\n%s: %s found at %#x, using IRQ %d.\n", - dev->name, name, ioaddr, dev->irq); + printk("\n"); ei_status.name = name; ei_status.tx_start_page = start_page; @@ -548,6 +547,8 @@ static int __init ne_probe1(struct net_device *dev, int ioaddr) ret = register_netdev(dev); if (ret) goto out_irq; + printk(KERN_INFO "%s: %s found at %#lx, using IRQ %d.\n", + dev->name, name, ioaddr, dev->irq); return 0; out_irq: -- cgit v1.2.3 From 1c08bf10658921dafae8d66be0effc915a209ab0 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 1 May 2007 00:27:49 +0900 Subject: ne: Add NEEDS_PORTLIST to control ISA auto-probe Add NEEDS_PORTLIST cpp macro to control ISA auto-probe. (I'm not sure M32R needs auto-probe but it is current behavior) Signed-off-by: Atsushi Nemoto Signed-off-by: Jeff Garzik --- drivers/net/ne.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 32ae91b0b61..22d6fe45375 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -78,8 +78,13 @@ static const char version2[] = /* Do we have a non std. amount of memory? (in units of 256 byte pages) */ /* #define PACKETBUF_MEMSIZE 0x40 */ +#if !defined(MODULE) && (defined(CONFIG_ISA) || defined(CONFIG_M32R)) +/* Do we need a portlist for the ISA auto-probe ? */ +#define NEEDS_PORTLIST +#endif + /* A zero-terminated list of I/O addresses to be probed at boot. */ -#ifndef MODULE +#ifdef NEEDS_PORTLIST static unsigned int netcard_portlist[] __initdata = { 0x300, 0x280, 0x320, 0x340, 0x360, 0x380, 0 }; @@ -186,7 +191,7 @@ static void ne_block_output(struct net_device *dev, const int count, static int __init do_ne_probe(struct net_device *dev) { unsigned long base_addr = dev->base_addr; -#ifndef MODULE +#ifdef NEEDS_PORTLIST int orig_irq = dev->irq; #endif @@ -202,7 +207,7 @@ static int __init do_ne_probe(struct net_device *dev) if (isapnp_present() && (ne_probe_isapnp(dev) == 0)) return 0; -#ifndef MODULE +#ifdef NEEDS_PORTLIST /* Last resort. The semi-risky ISA auto-probe. */ for (base_addr = 0; netcard_portlist[base_addr] != 0; base_addr++) { int ioaddr = netcard_portlist[base_addr]; -- cgit v1.2.3 From 57e386ce9d136261bc60a5223f39b179a3c11046 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 1 May 2007 00:27:58 +0900 Subject: ne: MIPS: Use platform_driver for ne on RBTX49XX This patch lets RBTX49XX boards use generic platform_driver interface for the ne driver. * Use platform_device to pass ioaddr and irq to the ne driver. * Remove unnecessary ifdefs for RBTX49XX from the ne driver. * Make the ne driver selectable on these boards regardless of CONFIG_ISA Signed-off-by: Atsushi Nemoto Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 2 +- drivers/net/ne.c | 8 -------- 2 files changed, 1 insertion(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 279ec625cec..372f25716b5 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -1104,7 +1104,7 @@ config ETH16I config NE2000 tristate "NE2000/NE1000 support" - depends on NET_ISA || (Q40 && m) || M32R + depends on NET_ISA || (Q40 && m) || M32R || TOSHIBA_RBTX4927 || TOSHIBA_RBTX4938 select CRC32 ---help--- If you have a network (Ethernet) card of this type, say Y and read diff --git a/drivers/net/ne.c b/drivers/net/ne.c index 22d6fe45375..c9f74bf5f49 100644 --- a/drivers/net/ne.c +++ b/drivers/net/ne.c @@ -56,10 +56,6 @@ static const char version2[] = #include #include -#if defined(CONFIG_TOSHIBA_RBTX4927) || defined(CONFIG_TOSHIBA_RBTX4938) -#include -#endif - #include "8390.h" #define DRV_NAME "ne" @@ -232,10 +228,6 @@ struct net_device * __init ne_probe(int unit) sprintf(dev->name, "eth%d", unit); netdev_boot_setup_check(dev); -#ifdef CONFIG_TOSHIBA_RBTX4938 - dev->base_addr = RBTX4938_RTL_8019_BASE; - dev->irq = RBTX4938_RTL_8019_IRQ; -#endif err = do_ne_probe(dev); if (err) goto out; -- cgit v1.2.3 From 44a1d2e5c5c935fff3a093a1bcede32912c76421 Mon Sep 17 00:00:00 2001 From: Stephen Hemminger Date: Mon, 30 Apr 2007 14:23:49 -0700 Subject: sky2: re-enable 88E8056 for most motherboards This fixes the regression in 2.6.21 for users with 88e8056 on motherboard. Allow all but the Gigabyte motherboard has some unresolved bus problems. Signed-off-by: Stephen Hemminger Signed-off-by: Jeff Garzik --- drivers/net/sky2.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/sky2.c b/drivers/net/sky2.c index 238c2ca34da..a307310f13f 100644 --- a/drivers/net/sky2.c +++ b/drivers/net/sky2.c @@ -124,10 +124,7 @@ static const struct pci_device_id sky2_id_table[] = { { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4361) }, /* 88E8050 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4362) }, /* 88E8053 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4363) }, /* 88E8055 */ -#ifdef broken - /* This device causes data corruption problems that are not resolved */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4364) }, /* 88E8056 */ -#endif { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4366) }, /* 88EC036 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4367) }, /* 88EC032 */ { PCI_DEVICE(PCI_VENDOR_ID_MARVELL, 0x4368) }, /* 88EC034 */ @@ -3581,10 +3578,21 @@ static int __devinit sky2_probe(struct pci_dev *pdev, goto err_out; } + /* Some Gigabyte motherboards have 88e8056 but cause problems + * There is some unresolved hardware related problem that causes + * descriptor errors and receive data corruption. + */ + if (pdev->vendor == PCI_VENDOR_ID_MARVELL && + pdev->device == 0x4364 && pdev->subsystem_vendor == 0x1458) { + dev_err(&pdev->dev, + "88E8056 on Gigabyte motherboards not supported\n"); + goto err_out_disable; + } + err = pci_request_regions(pdev, DRV_NAME); if (err) { dev_err(&pdev->dev, "cannot obtain PCI resources\n"); - goto err_out; + goto err_out_disable; } pci_set_master(pdev); @@ -3721,6 +3729,7 @@ err_out_free_hw: kfree(hw); err_out_free_regions: pci_release_regions(pdev); +err_out_disable: pci_disable_device(pdev); err_out: return err; -- cgit v1.2.3 From 0b45d18643f0a3eab09616b8a1283b013a7417ea Mon Sep 17 00:00:00 2001 From: Komuro Date: Sun, 6 May 2007 09:16:53 +0900 Subject: PCMCIA-NETDEV : xirc2ps_cs: bugfix of multicast code Dear Jeff Subject: [PATCH] xirc2ps_cs: bugfix of multicast code Signed-off-by: Komuro Signed-off-by: Jeff Garzik --- drivers/net/pcmcia/xirc2ps_cs.c | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pcmcia/xirc2ps_cs.c b/drivers/net/pcmcia/xirc2ps_cs.c index 809ec440b8e..258d6f39618 100644 --- a/drivers/net/pcmcia/xirc2ps_cs.c +++ b/drivers/net/pcmcia/xirc2ps_cs.c @@ -1420,7 +1420,7 @@ set_addresses(struct net_device *dev) kio_addr_t ioaddr = dev->base_addr; local_info_t *lp = netdev_priv(dev); struct dev_mc_list *dmi = dev->mc_list; - char *addr; + unsigned char *addr; int i,j,k,n; SelectPage(k=0x50); @@ -1429,6 +1429,9 @@ set_addresses(struct net_device *dev) if (++n > 9) break; i = 0; + if (n > 1 && n <= dev->mc_count && dmi) { + dmi = dmi->next; + } } if (j > 15) { j = 8; @@ -1436,10 +1439,9 @@ set_addresses(struct net_device *dev) SelectPage(k); } - if (n && n <= dev->mc_count && dmi) { + if (n && n <= dev->mc_count && dmi) addr = dmi->dmi_addr; - dmi = dmi->next; - } else + else addr = dev->dev_addr; if (lp->mohawk) @@ -1465,10 +1467,10 @@ set_multicast_list(struct net_device *dev) if (dev->flags & IFF_PROMISC) { /* snoop */ PutByte(XIRCREG42_SWC1, 0x06); /* set MPE and PME */ } else if (dev->mc_count > 9 || (dev->flags & IFF_ALLMULTI)) { - PutByte(XIRCREG42_SWC1, 0x06); /* set MPE */ + PutByte(XIRCREG42_SWC1, 0x02); /* set MPE */ } else if (dev->mc_count) { /* the chip can filter 9 addresses perfectly */ - PutByte(XIRCREG42_SWC1, 0x00); + PutByte(XIRCREG42_SWC1, 0x01); SelectPage(0x40); PutByte(XIRCREG40_CMD0, Offline); set_addresses(dev); -- cgit v1.2.3 From 6b4aea7352bed6e2fdb59a3fe24ce2b42b31c35a Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Thu, 3 May 2007 09:17:15 +0200 Subject: AT91RM9200 Ethernet: Support additional PHYs Add support for a number of new PHY's in the AT91RM9200 Ethernet driver. - Teridian 78Q21x3 - SMSC LAN83C185 (Patch from Luca Gamma) - National Semiconductor DP83848 (Patches from Ivan Kuten & Thomas Foldesi) Signed-off-by: Andrew Victor Signed-off-by: Jeff Garzik --- drivers/net/arm/at91_ether.c | 45 ++++++++++++++++++++++++++++++++++++++++ drivers/net/arm/at91_ether.h | 49 +++++++++++++++++++++++++------------------- 2 files changed, 73 insertions(+), 21 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index 152fa7a042b..b9cb5cb4d97 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -225,6 +225,16 @@ static irqreturn_t at91ether_phy_interrupt(int irq, void *dev_id) if (!(phy & ((1 << 2) | 1))) goto done; } + else if (lp->phy_type == MII_T78Q21x3_ID) { /* ack interrupt in Teridian PHY */ + read_phy(lp->phy_address, MII_T78Q21INT_REG, &phy); + if (!(phy & ((1 << 2) | 1))) + goto done; + } + else if (lp->phy_type == MII_DP83848_ID) { + read_phy(lp->phy_address, MII_DPPHYSTS_REG, &phy); /* ack interrupt in DP83848 PHY */ + if (!(phy & (1 << 7))) + goto done; + } update_linkspeed(dev, 0); @@ -280,6 +290,19 @@ static void enable_phyirq(struct net_device *dev) dsintr = (1 << 10) | ( 1 << 8); write_phy(lp->phy_address, MII_TPISTATUS, dsintr); } + else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */ + read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr); + dsintr = dsintr | 0x500; /* set bits 8, 10 */ + write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr); + } + else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */ + read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr); + dsintr = dsintr | 0x3c; /* set bits 2..5 */ + write_phy(lp->phy_address, MII_DPMISR_REG, dsintr); + read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr); + dsintr = dsintr | 0x3; /* set bits 0,1 */ + write_phy(lp->phy_address, MII_DPMICR_REG, dsintr); + } disable_mdi(); spin_unlock_irq(&lp->lock); @@ -323,6 +346,19 @@ static void disable_phyirq(struct net_device *dev) dsintr = ~((1 << 10) | (1 << 8)); write_phy(lp->phy_address, MII_TPISTATUS, dsintr); } + else if (lp->phy_type == MII_T78Q21x3_ID) { /* for Teridian PHY */ + read_phy(lp->phy_address, MII_T78Q21INT_REG, &dsintr); + dsintr = dsintr & ~0x500; /* clear bits 8, 10 */ + write_phy(lp->phy_address, MII_T78Q21INT_REG, dsintr); + } + else if (lp->phy_type == MII_DP83848_ID) { /* National Semiconductor DP83848 PHY */ + read_phy(lp->phy_address, MII_DPMICR_REG, &dsintr); + dsintr = dsintr & ~0x3; /* clear bits 0, 1 */ + write_phy(lp->phy_address, MII_DPMICR_REG, dsintr); + read_phy(lp->phy_address, MII_DPMISR_REG, &dsintr); + dsintr = dsintr & ~0x3c; /* clear bits 2..5 */ + write_phy(lp->phy_address, MII_DPMISR_REG, dsintr); + } disable_mdi(); spin_unlock_irq(&lp->lock); @@ -1062,10 +1098,16 @@ static int __init at91ether_setup(unsigned long phy_type, unsigned short phy_add printk(KERN_INFO "%s: Broadcom BCM5221 PHY\n", dev->name); else if (phy_type == MII_DP83847_ID) printk(KERN_INFO "%s: National Semiconductor DP83847 PHY\n", dev->name); + else if (phy_type == MII_DP83848_ID) + printk(KERN_INFO "%s: National Semiconductor DP83848 PHY\n", dev->name); else if (phy_type == MII_AC101L_ID) printk(KERN_INFO "%s: Altima AC101L PHY\n", dev->name); else if (phy_type == MII_KS8721_ID) printk(KERN_INFO "%s: Micrel KS8721 PHY\n", dev->name); + else if (phy_type == MII_T78Q21x3_ID) + printk(KERN_INFO "%s: Teridian 78Q21x3 PHY\n", dev->name); + else if (phy_type == MII_LAN83C185_ID) + printk(KERN_INFO "%s: SMSC LAN83C185 PHY\n", dev->name); return 0; } @@ -1103,8 +1145,11 @@ static int __init at91ether_probe(struct platform_device *pdev) case MII_RTL8201_ID: /* Realtek RTL8201: PHY_ID1 = 0, PHY_ID2 = 0x8201 */ case MII_BCM5221_ID: /* Broadcom BCM5221: PHY_ID1 = 0x40, PHY_ID2 = 0x61e0 */ case MII_DP83847_ID: /* National Semiconductor DP83847: */ + case MII_DP83848_ID: /* National Semiconductor DP83848: */ case MII_AC101L_ID: /* Altima AC101L: PHY_ID1 = 0x22, PHY_ID2 = 0x5520 */ case MII_KS8721_ID: /* Micrel KS8721: PHY_ID1 = 0x22, PHY_ID2 = 0x1610 */ + case MII_T78Q21x3_ID: /* Teridian 78Q21x3: PHY_ID1 = 0x0E, PHY_ID2 = 7237 */ + case MII_LAN83C185_ID: /* SMSC LAN83C185: PHY_ID1 = 0x0007, PHY_ID2 = 0xC0A1 */ detected = at91ether_setup(phy_id, phy_address, pdev, ether_clk); break; } diff --git a/drivers/net/arm/at91_ether.h b/drivers/net/arm/at91_ether.h index b6b665de2ea..a38fd2d053a 100644 --- a/drivers/net/arm/at91_ether.h +++ b/drivers/net/arm/at91_ether.h @@ -17,39 +17,46 @@ /* Davicom 9161 PHY */ -#define MII_DM9161_ID 0x0181b880 -#define MII_DM9161A_ID 0x0181b8a0 - -/* Davicom specific registers */ -#define MII_DSCR_REG 16 -#define MII_DSCSR_REG 17 -#define MII_DSINTR_REG 21 +#define MII_DM9161_ID 0x0181b880 +#define MII_DM9161A_ID 0x0181b8a0 +#define MII_DSCR_REG 16 +#define MII_DSCSR_REG 17 +#define MII_DSINTR_REG 21 /* Intel LXT971A PHY */ -#define MII_LXT971A_ID 0x001378E0 - -/* Intel specific registers */ -#define MII_ISINTE_REG 18 -#define MII_ISINTS_REG 19 -#define MII_LEDCTRL_REG 20 +#define MII_LXT971A_ID 0x001378E0 +#define MII_ISINTE_REG 18 +#define MII_ISINTS_REG 19 +#define MII_LEDCTRL_REG 20 /* Realtek RTL8201 PHY */ -#define MII_RTL8201_ID 0x00008200 +#define MII_RTL8201_ID 0x00008200 /* Broadcom BCM5221 PHY */ -#define MII_BCM5221_ID 0x004061e0 - -/* Broadcom specific registers */ -#define MII_BCMINTR_REG 26 +#define MII_BCM5221_ID 0x004061e0 +#define MII_BCMINTR_REG 26 /* National Semiconductor DP83847 */ -#define MII_DP83847_ID 0x20005c30 +#define MII_DP83847_ID 0x20005c30 + +/* National Semiconductor DP83848 */ +#define MII_DP83848_ID 0x20005c90 +#define MII_DPPHYSTS_REG 16 +#define MII_DPMICR_REG 17 +#define MII_DPMISR_REG 18 /* Altima AC101L PHY */ -#define MII_AC101L_ID 0x00225520 +#define MII_AC101L_ID 0x00225520 /* Micrel KS8721 PHY */ -#define MII_KS8721_ID 0x00221610 +#define MII_KS8721_ID 0x00221610 + +/* Teridian 78Q2123/78Q2133 */ +#define MII_T78Q21x3_ID 0x000e7230 +#define MII_T78Q21INT_REG 17 + +/* SMSC LAN83C185 */ +#define MII_LAN83C185_ID 0x0007C0A0 /* ........................................................................ */ -- cgit v1.2.3 From 8bc354730bc877ebdf35c692460b01e624934aea Mon Sep 17 00:00:00 2001 From: Andrew Victor Date: Wed, 2 May 2007 12:11:38 +0200 Subject: AT91RM9200 Ethernet: Fix multicast addressing The order that the two 32-bit words written to the Hash Address (Low, High) Registers for matching of multicast addresses is incorrect. Signed-off-by: Lars Reemts Signed-off-by: Andrew Victor Signed-off-by: Jeff Garzik --- drivers/net/arm/at91_ether.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/arm/at91_ether.c b/drivers/net/arm/at91_ether.c index b9cb5cb4d97..ef2cc80256a 100644 --- a/drivers/net/arm/at91_ether.c +++ b/drivers/net/arm/at91_ether.c @@ -571,8 +571,8 @@ static void at91ether_sethashtable(struct net_device *dev) mc_filter[bitnr >> 5] |= 1 << (bitnr & 31); } - at91_emac_write(AT91_EMAC_HSH, mc_filter[0]); - at91_emac_write(AT91_EMAC_HSL, mc_filter[1]); + at91_emac_write(AT91_EMAC_HSL, mc_filter[0]); + at91_emac_write(AT91_EMAC_HSH, mc_filter[1]); } /* -- cgit v1.2.3 From 6478fac6c31cbf45e8b818880728238e0c548d57 Mon Sep 17 00:00:00 2001 From: Richard Knutsson Date: Tue, 1 May 2007 18:43:27 +0200 Subject: drivers/net/dm9000: Convert to generic boolean Convert to generic boolean. Signed-off-by: Richard Knutsson Signed-off-by: Jeff Garzik --- drivers/net/dm9000.c | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/dm9000.c b/drivers/net/dm9000.c index 0e338539b82..264fa0e2e07 100644 --- a/drivers/net/dm9000.c +++ b/drivers/net/dm9000.c @@ -77,9 +77,6 @@ #define DM9000_PHY 0x40 /* PHY address 0x01 */ -#define TRUE 1 -#define FALSE 0 - #define CARDNAME "dm9000" #define PFX CARDNAME ": " @@ -896,7 +893,7 @@ dm9000_rx(struct net_device *dev) struct dm9000_rxhdr rxhdr; struct sk_buff *skb; u8 rxbyte, *rdptr; - int GoodPacket; + bool GoodPacket; int RxLen; /* Check packet ready or not */ @@ -918,7 +915,7 @@ dm9000_rx(struct net_device *dev) return; /* A packet ready now & Get status/length */ - GoodPacket = TRUE; + GoodPacket = true; writeb(DM9000_MRCMD, db->io_addr); (db->inblk)(db->io_data, &rxhdr, sizeof(rxhdr)); @@ -927,7 +924,7 @@ dm9000_rx(struct net_device *dev) /* Packet Status check */ if (RxLen < 0x40) { - GoodPacket = FALSE; + GoodPacket = false; PRINTK1("Bad Packet received (runt)\n"); } @@ -936,7 +933,7 @@ dm9000_rx(struct net_device *dev) } if (rxhdr.RxStatus & 0xbf00) { - GoodPacket = FALSE; + GoodPacket = false; if (rxhdr.RxStatus & 0x100) { PRINTK1("fifo error\n"); db->stats.rx_fifo_errors++; -- cgit v1.2.3 From 418aea75246d5f83caa3a003fd66fe3b1aa01738 Mon Sep 17 00:00:00 2001 From: Atsushi Nemoto Date: Tue, 8 May 2007 00:46:04 +0900 Subject: tc35815: Remove unnecessary skb->dev assignment Apply changes in commit 4c13eb6657fe9ef7b4dc8f1a405c902e9e5234e0 to newly added piece of code. Signed-off-by: Atsushi Nemoto Signed-off-by: Jeff Garzik --- drivers/net/tc35815.c | 1 - 1 file changed, 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/tc35815.c b/drivers/net/tc35815.c index f1e2dfc795a..463d600ed83 100644 --- a/drivers/net/tc35815.c +++ b/drivers/net/tc35815.c @@ -540,7 +540,6 @@ static struct sk_buff *alloc_rxbuf_skb(struct net_device *dev, skb = dev_alloc_skb(RX_BUF_SIZE); if (!skb) return NULL; - skb->dev = dev; *dma_handle = pci_map_single(hwdev, skb->data, RX_BUF_SIZE, PCI_DMA_FROMDEVICE); if (pci_dma_mapping_error(*dma_handle)) { -- cgit v1.2.3 From 771f7404a9deca902594823d616cd7a84f827982 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 8 May 2007 00:47:21 -0500 Subject: pasemi_mac: Move the IRQ mapping from the PCI layer to the driver Fixes for ethernet IRQ mapping, to be done in the driver instead of in the platform setup code. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 30 +++++++++++++++++++++--------- drivers/net/pasemi_mac.h | 2 ++ 2 files changed, 23 insertions(+), 9 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index bde833542b6..c7995d77ccf 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -33,6 +33,8 @@ #include #include +#include + #include "pasemi_mac.h" @@ -531,6 +533,7 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) static int pasemi_mac_open(struct net_device *dev) { struct pasemi_mac *mac = netdev_priv(dev); + int base_irq; unsigned int flags; int ret; @@ -594,28 +597,37 @@ static int pasemi_mac_open(struct net_device *dev) netif_start_queue(dev); netif_poll_enable(dev); - ret = request_irq(mac->dma_pdev->irq + mac->dma_txch, - &pasemi_mac_tx_intr, IRQF_DISABLED, + /* Interrupts are a bit different for our DMA controller: While + * it's got one a regular PCI device header, the interrupt there + * is really the base of the range it's using. Each tx and rx + * channel has it's own interrupt source. + */ + + base_irq = virq_to_hw(mac->dma_pdev->irq); + + mac->tx_irq = irq_create_mapping(NULL, base_irq + mac->dma_txch); + mac->rx_irq = irq_create_mapping(NULL, base_irq + 20 + mac->dma_txch); + + ret = request_irq(mac->tx_irq, &pasemi_mac_tx_intr, IRQF_DISABLED, mac->tx->irq_name, dev); if (ret) { dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", - mac->dma_pdev->irq + mac->dma_txch, ret); + base_irq + mac->dma_txch, ret); goto out_tx_int; } - ret = request_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, - &pasemi_mac_rx_intr, IRQF_DISABLED, + ret = request_irq(mac->rx_irq, &pasemi_mac_rx_intr, IRQF_DISABLED, mac->rx->irq_name, dev); if (ret) { dev_err(&mac->pdev->dev, "request_irq of irq %d failed: %d\n", - mac->dma_pdev->irq + 20 + mac->dma_rxch, ret); + base_irq + 20 + mac->dma_rxch, ret); goto out_rx_int; } return 0; out_rx_int: - free_irq(mac->dma_pdev->irq + mac->dma_txch, dev); + free_irq(mac->tx_irq, dev); out_tx_int: netif_poll_disable(dev); netif_stop_queue(dev); @@ -699,8 +711,8 @@ static int pasemi_mac_close(struct net_device *dev) pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), 0); - free_irq(mac->dma_pdev->irq + mac->dma_txch, dev); - free_irq(mac->dma_pdev->irq + 20 + mac->dma_rxch, dev); + free_irq(mac->tx_irq, dev); + free_irq(mac->rx_irq, dev); /* Free resources */ pasemi_mac_free_rx_resources(dev); diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index c3e37e46a18..703f1b0d434 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h @@ -73,6 +73,8 @@ struct pasemi_mac { struct pasemi_mac_txring *tx; struct pasemi_mac_rxring *rx; + unsigned long tx_irq; + unsigned long rx_irq; }; /* Software status descriptor (desc_info) */ -- cgit v1.2.3 From 1b0335ea30bf85eecffd21be64b7653407d6259a Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 8 May 2007 00:47:26 -0500 Subject: pasemi_mac: Abstract and fix up interrupt restart routines Abstract out (and fix up) the interrupt restart routines, making sure we start out in a consistent state. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 44 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 41 insertions(+), 3 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index c7995d77ccf..73e79f35a42 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -362,6 +362,42 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) mac->rx->next_to_fill += count; } +static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) +{ + unsigned int reg, stat; + /* Re-enable packet count interrupts: finally + * ack the packet count interrupt we got in rx_intr. + */ + + pci_read_config_dword(mac->iob_pdev, + PAS_IOB_DMA_RXCH_STAT(mac->dma_rxch), + &stat); + + reg = PAS_IOB_DMA_RXCH_RESET_PCNT(stat & PAS_IOB_DMA_RXCH_STAT_CNTDEL_M) + | PAS_IOB_DMA_RXCH_RESET_PINTC; + + pci_write_config_dword(mac->iob_pdev, + PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), + reg); +} + +static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) +{ + unsigned int reg, stat; + + /* Re-enable packet count interrupts */ + pci_read_config_dword(mac->iob_pdev, + PAS_IOB_DMA_TXCH_STAT(mac->dma_txch), &stat); + + reg = PAS_IOB_DMA_TXCH_RESET_PCNT(stat & PAS_IOB_DMA_TXCH_STAT_CNTDEL_M) + | PAS_IOB_DMA_TXCH_RESET_PINTC; + + pci_write_config_dword(mac->iob_pdev, + PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); +} + + + static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) { unsigned int i; @@ -559,6 +595,10 @@ static int pasemi_mac_open(struct net_device *dev) pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), PAS_IOB_DMA_RXCH_CFG_CNTTH(30)); + /* Clear out any residual packet count state from firmware */ + pasemi_mac_restart_rx_intr(mac); + pasemi_mac_restart_tx_intr(mac); + pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000)); @@ -835,9 +875,7 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget) /* all done, no more packets present */ netif_rx_complete(dev); - /* re-enable receive interrupts */ - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000)); + pasemi_mac_restart_rx_intr(mac); return 0; } else { /* used up our quantum, so reschedule */ -- cgit v1.2.3 From 6dfa7522d8b08c887bf9f4cb2600b89232f132f5 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 8 May 2007 00:47:32 -0500 Subject: pasemi_mac: Timer and interrupt fixes Timer and interrupt fixes: * Be pickier with what kind of interrupts are acked to avoid the device to get out of sync with the driver state * Set RX count threshhold to 1 (for NAPI interrupted mode), TX count threshold to 32. * Set timer thresholds to current max (~16ms). Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 41 +++++++++++++++++++++++++++++------------ drivers/net/pasemi_mac.h | 1 + 2 files changed, 30 insertions(+), 12 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 73e79f35a42..2bf13cf5535 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -526,18 +526,28 @@ static irqreturn_t pasemi_mac_rx_intr(int irq, void *data) struct pasemi_mac *mac = netdev_priv(dev); unsigned int reg; - if (!(*mac->rx_status & PAS_STATUS_INT)) + if (!(*mac->rx_status & PAS_STATUS_CAUSE_M)) return IRQ_NONE; - netif_rx_schedule(dev); - pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0)); + if (*mac->rx_status & PAS_STATUS_ERROR) + printk("rx_status reported error\n"); + + /* Don't reset packet count so it won't fire again but clear + * all others. + */ + + pci_read_config_dword(mac->dma_pdev, PAS_DMA_RXINT_RCMDSTA(mac->dma_if), ®); - reg = PAS_IOB_DMA_RXCH_RESET_PINTC | PAS_IOB_DMA_RXCH_RESET_SINTC | - PAS_IOB_DMA_RXCH_RESET_DINTC; + reg = 0; + if (*mac->rx_status & PAS_STATUS_SOFT) + reg |= PAS_IOB_DMA_RXCH_RESET_SINTC; + if (*mac->rx_status & PAS_STATUS_ERROR) + reg |= PAS_IOB_DMA_RXCH_RESET_DINTC; if (*mac->rx_status & PAS_STATUS_TIMER) reg |= PAS_IOB_DMA_RXCH_RESET_TINTC; + netif_rx_schedule(dev); + pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_RESET(mac->dma_rxch), reg); @@ -551,14 +561,17 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) struct pasemi_mac *mac = netdev_priv(dev); unsigned int reg; - if (!(*mac->tx_status & PAS_STATUS_INT)) + if (!(*mac->tx_status & PAS_STATUS_CAUSE_M)) return IRQ_NONE; pasemi_mac_clean_tx(mac); - reg = PAS_IOB_DMA_TXCH_RESET_PINTC | PAS_IOB_DMA_TXCH_RESET_SINTC; - if (*mac->tx_status & PAS_STATUS_TIMER) - reg |= PAS_IOB_DMA_TXCH_RESET_TINTC; + reg = PAS_IOB_DMA_TXCH_RESET_PINTC; + + if (*mac->tx_status & PAS_STATUS_SOFT) + reg |= PAS_IOB_DMA_TXCH_RESET_SINTC; + if (*mac->tx_status & PAS_STATUS_ERROR) + reg |= PAS_IOB_DMA_TXCH_RESET_DINTC; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_RESET(mac->dma_txch), reg); @@ -593,14 +606,18 @@ static int pasemi_mac_open(struct net_device *dev) flags |= PAS_MAC_CFG_PCFG_TSR_1G | PAS_MAC_CFG_PCFG_SPD_1G; pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_RXCH_CFG(mac->dma_rxch), - PAS_IOB_DMA_RXCH_CFG_CNTTH(30)); + PAS_IOB_DMA_RXCH_CFG_CNTTH(1)); + + pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_TXCH_CFG(mac->dma_txch), + PAS_IOB_DMA_TXCH_CFG_CNTTH(32)); /* Clear out any residual packet count state from firmware */ pasemi_mac_restart_rx_intr(mac); pasemi_mac_restart_tx_intr(mac); + /* 0xffffff is max value, about 16ms */ pci_write_config_dword(mac->iob_pdev, PAS_IOB_DMA_COM_TIMEOUTCFG, - PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(1000000)); + PAS_IOB_DMA_COM_TIMEOUTCFG_TCNT(0xffffff)); pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, flags); diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index 703f1b0d434..88edaa51c66 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h @@ -299,6 +299,7 @@ enum { #define PAS_STATUS_DCNT_S 16 #define PAS_STATUS_BPCNT_M 0x0000ffff00000000ull #define PAS_STATUS_BPCNT_S 32 +#define PAS_STATUS_CAUSE_M 0xf000000000000000ull #define PAS_STATUS_TIMER 0x1000000000000000ull #define PAS_STATUS_ERROR 0x2000000000000000ull #define PAS_STATUS_SOFT 0x4000000000000000ull -- cgit v1.2.3 From 9f05cfe250498791cd24707aea3b728b52d886d5 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 8 May 2007 00:47:37 -0500 Subject: pasemi_mac: Add SKB reuse / copy-break Add a copy-break and recycle the SKB in the driver for small packets. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 31 ++++++++++++++++++++++++------- 1 file changed, 24 insertions(+), 7 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 2bf13cf5535..216bb4a2c63 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -279,8 +279,8 @@ static void pasemi_mac_free_rx_resources(struct net_device *dev) for (i = 0; i < RX_RING_SIZE; i++) { info = &RX_DESC_INFO(mac, i); dp = &RX_DESC(mac, i); - if (info->dma) { - if (info->skb) { + if (info->skb) { + if (info->dma) { pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len, @@ -329,12 +329,14 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) struct sk_buff *skb; dma_addr_t dma; - skb = dev_alloc_skb(BUF_SIZE); + /* skb might still be in there for recycle on short receives */ + if (info->skb) + skb = info->skb; + else + skb = dev_alloc_skb(BUF_SIZE); - if (!skb) { - count = i - start; + if (unlikely(!skb)) break; - } dma = pci_map_single(mac->dma_pdev, skb->data, skb->len, PCI_DMA_FROMDEVICE); @@ -442,13 +444,28 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) BUG_ON(!info); BUG_ON(info->dma != dma); + skb = info->skb; pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len, PCI_DMA_FROMDEVICE); + info->dma = 0; - skb = info->skb; len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; + if (len < 256) { + struct sk_buff *new_skb = + netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN); + if (new_skb) { + skb_reserve(new_skb, NET_IP_ALIGN); + memcpy(new_skb->data - NET_IP_ALIGN, + skb->data - NET_IP_ALIGN, + len + NET_IP_ALIGN); + /* save the skb in buffer_info as good */ + skb = new_skb; + } + /* else just continue with the old one */ + } else + info->skb = NULL; skb_put(skb, len); -- cgit v1.2.3 From cfa8007d5cee58d2c2121b7d00077c6f10969cb7 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 8 May 2007 00:47:41 -0500 Subject: pasemi_mac: Minor cleanup / define fixes * Remove some unused defines * Fix a couple of wrong chip register defines, and add a few more fields that might be used in the near future. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 6 ------ drivers/net/pasemi_mac.h | 12 ++++++++---- 2 files changed, 8 insertions(+), 10 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 216bb4a2c63..f18fd07973b 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -61,12 +61,6 @@ #define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */ -/* XXXOJN these should come out of the device tree some day */ -#define PAS_DMA_CAP_BASE 0xe00d0040 -#define PAS_DMA_CAP_SIZE 0x100 -#define PAS_DMA_COM_BASE 0xe00d0100 -#define PAS_DMA_COM_SIZE 0x100 - static struct pasdma_status *dma_status; static int pasemi_get_mac_addr(struct pasemi_mac *mac) diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index 88edaa51c66..3dcc1f288ad 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h @@ -195,11 +195,15 @@ enum { #define PAS_DMA_RXINT_RCMDSTA(i) (0x200+(i)*_PAS_DMA_RXINT_STRIDE) #define PAS_DMA_RXINT_RCMDSTA_EN 0x00000001 #define PAS_DMA_RXINT_RCMDSTA_ST 0x00000002 -#define PAS_DMA_RXINT_RCMDSTA_OO 0x00000100 -#define PAS_DMA_RXINT_RCMDSTA_BP 0x00000200 -#define PAS_DMA_RXINT_RCMDSTA_DR 0x00000400 +#define PAS_DMA_RXINT_RCMDSTA_MBT 0x00000008 +#define PAS_DMA_RXINT_RCMDSTA_MDR 0x00000010 +#define PAS_DMA_RXINT_RCMDSTA_MOO 0x00000020 +#define PAS_DMA_RXINT_RCMDSTA_MBP 0x00000040 #define PAS_DMA_RXINT_RCMDSTA_BT 0x00000800 -#define PAS_DMA_RXINT_RCMDSTA_TB 0x00001000 +#define PAS_DMA_RXINT_RCMDSTA_DR 0x00001000 +#define PAS_DMA_RXINT_RCMDSTA_OO 0x00002000 +#define PAS_DMA_RXINT_RCMDSTA_BP 0x00004000 +#define PAS_DMA_RXINT_RCMDSTA_TB 0x00008000 #define PAS_DMA_RXINT_RCMDSTA_ACT 0x00010000 #define PAS_DMA_RXINT_RCMDSTA_DROPS_M 0xfffe0000 #define PAS_DMA_RXINT_RCMDSTA_DROPS_S 17 -- cgit v1.2.3 From cd4ceb245be7926e94558e2b6cd279bfaa775908 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 8 May 2007 00:47:45 -0500 Subject: pasemi_mac: Logic cleanup / rx performance improvements Logic cleanup and some performance enhancements to the RX path. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 75 ++++++++++++++++++++++++------------------------ 1 file changed, 37 insertions(+), 38 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index f18fd07973b..6b4e925aa7f 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -305,19 +305,20 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) struct pasemi_mac *mac = netdev_priv(dev); unsigned int i; int start = mac->rx->next_to_fill; - unsigned int count; + unsigned int limit, count; - count = (mac->rx->next_to_clean + RX_RING_SIZE - + limit = (mac->rx->next_to_clean + RX_RING_SIZE - mac->rx->next_to_fill) & (RX_RING_SIZE - 1); /* Check to see if we're doing first-time setup */ if (unlikely(mac->rx->next_to_clean == 0 && mac->rx->next_to_fill == 0)) - count = RX_RING_SIZE; + limit = RX_RING_SIZE; - if (count <= 0) + if (limit <= 0) return; - for (i = start; i < start + count; i++) { + i = start; + for (count = limit; count; count--) { struct pasemi_mac_buffer *info = &RX_DESC_INFO(mac, i); u64 *buff = &RX_BUFF(mac, i); struct sk_buff *skb; @@ -335,27 +336,27 @@ static void pasemi_mac_replenish_rx_ring(struct net_device *dev) dma = pci_map_single(mac->dma_pdev, skb->data, skb->len, PCI_DMA_FROMDEVICE); - if (dma_mapping_error(dma)) { + if (unlikely(dma_mapping_error(dma))) { dev_kfree_skb_irq(info->skb); - count = i - start; break; } info->skb = skb; info->dma = dma; *buff = XCT_RXB_LEN(BUF_SIZE) | XCT_RXB_ADDR(dma); + i++; } wmb(); pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXCHAN_INCR(mac->dma_rxch), - count); + limit - count); pci_write_config_dword(mac->dma_pdev, PAS_DMA_RXINT_INCR(mac->dma_if), - count); + limit - count); - mac->rx->next_to_fill += count; + mac->rx->next_to_fill += limit - count; } static void pasemi_mac_restart_rx_intr(struct pasemi_mac *mac) @@ -393,32 +394,31 @@ static void pasemi_mac_restart_tx_intr(struct pasemi_mac *mac) } - static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) { - unsigned int i; - int start, count; + unsigned int n; + int count; + struct pas_dma_xct_descr *dp; + struct pasemi_mac_buffer *info; + struct sk_buff *skb; + unsigned int i, len; + u64 macrx; + dma_addr_t dma; spin_lock(&mac->rx->lock); - start = mac->rx->next_to_clean; - count = 0; + n = mac->rx->next_to_clean; - for (i = start; i < (start + RX_RING_SIZE) && count < limit; i++) { - struct pas_dma_xct_descr *dp; - struct pasemi_mac_buffer *info; - struct sk_buff *skb; - unsigned int j, len; - dma_addr_t dma; + for (count = limit; count; count--) { rmb(); - dp = &RX_DESC(mac, i); + dp = &RX_DESC(mac, n); + macrx = dp->macrx; - if (!(dp->macrx & XCT_MACRX_O)) + if (!(macrx & XCT_MACRX_O)) break; - count++; info = NULL; @@ -430,22 +430,20 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) */ dma = (dp->ptr & XCT_PTR_ADDR_M); - for (j = start; j < (start + RX_RING_SIZE); j++) { - info = &RX_DESC_INFO(mac, j); + for (i = n; i < (n + RX_RING_SIZE); i++) { + info = &RX_DESC_INFO(mac, i); if (info->dma == dma) break; } - BUG_ON(!info); - BUG_ON(info->dma != dma); skb = info->skb; + info->dma = 0; - pci_unmap_single(mac->dma_pdev, info->dma, info->skb->len, + pci_unmap_single(mac->dma_pdev, dma, skb->len, PCI_DMA_FROMDEVICE); - info->dma = 0; + len = (macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; - len = (dp->macrx & XCT_MACRX_LLEN_M) >> XCT_MACRX_LLEN_S; if (len < 256) { struct sk_buff *new_skb = netdev_alloc_skb(mac->netdev, len + NET_IP_ALIGN); @@ -465,9 +463,9 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) skb->protocol = eth_type_trans(skb, mac->netdev); - if ((dp->macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) { + if ((macrx & XCT_MACRX_HTY_M) == XCT_MACRX_HTY_IPV4_OK) { skb->ip_summed = CHECKSUM_COMPLETE; - skb->csum = (dp->macrx & XCT_MACRX_CSUM_M) >> + skb->csum = (macrx & XCT_MACRX_CSUM_M) >> XCT_MACRX_CSUM_S; } else skb->ip_summed = CHECKSUM_NONE; @@ -477,13 +475,13 @@ static int pasemi_mac_clean_rx(struct pasemi_mac *mac, int limit) netif_receive_skb(skb); - info->dma = 0; - info->skb = NULL; dp->ptr = 0; dp->macrx = 0; + + n++; } - mac->rx->next_to_clean += count; + mac->rx->next_to_clean += limit - count; pasemi_mac_replenish_rx_ring(mac->netdev); spin_unlock(&mac->rx->lock); @@ -899,6 +897,9 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget) pkts = pasemi_mac_clean_rx(mac, limit); + dev->quota -= pkts; + *budget -= pkts; + if (pkts < limit) { /* all done, no more packets present */ netif_rx_complete(dev); @@ -907,8 +908,6 @@ static int pasemi_mac_poll(struct net_device *dev, int *budget) return 0; } else { /* used up our quantum, so reschedule */ - dev->quota -= pkts; - *budget -= pkts; return 1; } } -- cgit v1.2.3 From ceb51361370c003e13f782edb7171a8383e5c849 Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 8 May 2007 00:47:49 -0500 Subject: pasemi_mac: Add msglevel support and "debug" module param Add msglevel support for pasemi_mac. Move the MODULE_* defines to the top to go together with the variable (similar to tg3). Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 25 +++++++++++++++++++++---- drivers/net/pasemi_mac.h | 2 ++ 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 6b4e925aa7f..4c6d34d6989 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -53,6 +53,16 @@ #define RX_RING_SIZE 512 #define TX_RING_SIZE 512 +#define DEFAULT_MSG_ENABLE \ + (NETIF_MSG_DRV | \ + NETIF_MSG_PROBE | \ + NETIF_MSG_LINK | \ + NETIF_MSG_TIMER | \ + NETIF_MSG_IFDOWN | \ + NETIF_MSG_IFUP | \ + NETIF_MSG_RX_ERR | \ + NETIF_MSG_TX_ERR) + #define TX_DESC(mac, num) ((mac)->tx->desc[(num) & (TX_RING_SIZE-1)]) #define TX_DESC_INFO(mac, num) ((mac)->tx->desc_info[(num) & (TX_RING_SIZE-1)]) #define RX_DESC(mac, num) ((mac)->rx->desc[(num) & (RX_RING_SIZE-1)]) @@ -61,6 +71,14 @@ #define BUF_SIZE 1646 /* 1500 MTU + ETH_HLEN + VLAN_HLEN + 2 64B cachelines */ +MODULE_LICENSE("GPL"); +MODULE_AUTHOR ("Olof Johansson "); +MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver"); + +static int debug = -1; /* -1 == use DEFAULT_MSG_ENABLE as value */ +module_param(debug, int, 0); +MODULE_PARM_DESC(debug, "PA Semi MAC bitmapped debugging message enable value"); + static struct pasdma_status *dma_status; static int pasemi_get_mac_addr(struct pasemi_mac *mac) @@ -873,6 +891,7 @@ static struct net_device_stats *pasemi_mac_get_stats(struct net_device *dev) return &mac->stats; } + static void pasemi_mac_set_rx_mode(struct net_device *dev) { struct pasemi_mac *mac = netdev_priv(dev); @@ -1007,6 +1026,8 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mac->rx_status = &dma_status->rx_sta[mac->dma_rxch]; mac->tx_status = &dma_status->tx_sta[mac->dma_txch]; + mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + err = register_netdev(dev); if (err) { @@ -1081,9 +1102,5 @@ int pasemi_mac_init_module(void) return pci_register_driver(&pasemi_mac_driver); } -MODULE_LICENSE("GPL"); -MODULE_AUTHOR ("Olof Johansson "); -MODULE_DESCRIPTION("PA Semi PWRficient Ethernet driver"); - module_init(pasemi_mac_init_module); module_exit(pasemi_mac_cleanup_module); diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index 3dcc1f288ad..6539de1c2f2 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h @@ -75,6 +75,8 @@ struct pasemi_mac { struct pasemi_mac_rxring *rx; unsigned long tx_irq; unsigned long rx_irq; + + unsigned int msg_enable; }; /* Software status descriptor (desc_info) */ -- cgit v1.2.3 From bb6e9590792834f905a92e439a083254649c985c Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 8 May 2007 00:47:54 -0500 Subject: pasemi_mac: PHY support PHY support for pasemi_mac. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/Kconfig | 1 + drivers/net/pasemi_mac.c | 126 +++++++++++++++++++++++++++++++++++++++++++++++ drivers/net/pasemi_mac.h | 6 +++ 3 files changed, 133 insertions(+) (limited to 'drivers/net') diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig index 372f25716b5..b86ccd2ecd5 100644 --- a/drivers/net/Kconfig +++ b/drivers/net/Kconfig @@ -2488,6 +2488,7 @@ config NETXEN_NIC config PASEMI_MAC tristate "PA Semi 1/10Gbit MAC" depends on PPC64 && PCI + select PHYLIB help This driver supports the on-chip 1/10Gbit Ethernet controller on PA Semi's PWRficient line of chips. diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 4c6d34d6989..78b127c404e 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -606,6 +606,114 @@ static irqreturn_t pasemi_mac_tx_intr(int irq, void *data) return IRQ_HANDLED; } +static void pasemi_adjust_link(struct net_device *dev) +{ + struct pasemi_mac *mac = netdev_priv(dev); + int msg; + unsigned int flags; + unsigned int new_flags; + + if (!mac->phydev->link) { + /* If no link, MAC speed settings don't matter. Just report + * link down and return. + */ + if (mac->link && netif_msg_link(mac)) + printk(KERN_INFO "%s: Link is down.\n", dev->name); + + netif_carrier_off(dev); + mac->link = 0; + + return; + } else + netif_carrier_on(dev); + + pci_read_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, &flags); + new_flags = flags & ~(PAS_MAC_CFG_PCFG_HD | PAS_MAC_CFG_PCFG_SPD_M | + PAS_MAC_CFG_PCFG_TSR_M); + + if (!mac->phydev->duplex) + new_flags |= PAS_MAC_CFG_PCFG_HD; + + switch (mac->phydev->speed) { + case 1000: + new_flags |= PAS_MAC_CFG_PCFG_SPD_1G | + PAS_MAC_CFG_PCFG_TSR_1G; + break; + case 100: + new_flags |= PAS_MAC_CFG_PCFG_SPD_100M | + PAS_MAC_CFG_PCFG_TSR_100M; + break; + case 10: + new_flags |= PAS_MAC_CFG_PCFG_SPD_10M | + PAS_MAC_CFG_PCFG_TSR_10M; + break; + default: + printk("Unsupported speed %d\n", mac->phydev->speed); + } + + /* Print on link or speed/duplex change */ + msg = mac->link != mac->phydev->link || flags != new_flags; + + mac->duplex = mac->phydev->duplex; + mac->speed = mac->phydev->speed; + mac->link = mac->phydev->link; + + if (new_flags != flags) + pci_write_config_dword(mac->pdev, PAS_MAC_CFG_PCFG, new_flags); + + if (msg && netif_msg_link(mac)) + printk(KERN_INFO "%s: Link is up at %d Mbps, %s duplex.\n", + dev->name, mac->speed, mac->duplex ? "full" : "half"); +} + +static int pasemi_mac_phy_init(struct net_device *dev) +{ + struct pasemi_mac *mac = netdev_priv(dev); + struct device_node *dn, *phy_dn; + struct phy_device *phydev; + unsigned int phy_id; + const phandle *ph; + const unsigned int *prop; + struct resource r; + int ret; + + dn = pci_device_to_OF_node(mac->pdev); + ph = get_property(dn, "phy-handle", NULL); + if (!ph) + return -ENODEV; + phy_dn = of_find_node_by_phandle(*ph); + + prop = get_property(phy_dn, "reg", NULL); + ret = of_address_to_resource(phy_dn->parent, 0, &r); + if (ret) + goto err; + + phy_id = *prop; + snprintf(mac->phy_id, BUS_ID_SIZE, PHY_ID_FMT, (int)r.start, phy_id); + + of_node_put(phy_dn); + + mac->link = 0; + mac->speed = 0; + mac->duplex = -1; + + phydev = phy_connect(dev, mac->phy_id, &pasemi_adjust_link, 0, PHY_INTERFACE_MODE_SGMII); + + if (IS_ERR(phydev)) { + printk(KERN_ERR "%s: Could not attach to phy\n", dev->name); + return PTR_ERR(phydev); + } + + mac->phydev = phydev; + + return 0; + +err: + of_node_put(phy_dn); + return -ENODEV; +} + + static int pasemi_mac_open(struct net_device *dev) { struct pasemi_mac *mac = netdev_priv(dev); @@ -678,6 +786,13 @@ static int pasemi_mac_open(struct net_device *dev) pasemi_mac_replenish_rx_ring(dev); + ret = pasemi_mac_phy_init(dev); + /* Some configs don't have PHYs (XAUI etc), so don't complain about + * failed init due to -ENODEV. + */ + if (ret && ret != -ENODEV) + dev_warn(&mac->pdev->dev, "phy init failed: %d\n", ret); + netif_start_queue(dev); netif_poll_enable(dev); @@ -708,6 +823,9 @@ static int pasemi_mac_open(struct net_device *dev) goto out_rx_int; } + if (mac->phydev) + phy_start(mac->phydev); + return 0; out_rx_int: @@ -731,6 +849,11 @@ static int pasemi_mac_close(struct net_device *dev) unsigned int stat; int retries; + if (mac->phydev) { + phy_stop(mac->phydev); + phy_disconnect(mac->phydev); + } + netif_stop_queue(dev); /* Clean out any pending buffers */ @@ -1028,6 +1151,9 @@ pasemi_mac_probe(struct pci_dev *pdev, const struct pci_device_id *ent) mac->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); + /* Enable most messages by default */ + mac->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1; + err = register_netdev(dev); if (err) { diff --git a/drivers/net/pasemi_mac.h b/drivers/net/pasemi_mac.h index 6539de1c2f2..8bc0cea8b14 100644 --- a/drivers/net/pasemi_mac.h +++ b/drivers/net/pasemi_mac.h @@ -24,6 +24,7 @@ #include #include #include +#include struct pasemi_mac_txring { spinlock_t lock; @@ -54,6 +55,7 @@ struct pasemi_mac { struct pci_dev *pdev; struct pci_dev *dma_pdev; struct pci_dev *iob_pdev; + struct phy_device *phydev; struct net_device_stats stats; /* Pointer to the cacheable per-channel status registers */ @@ -75,8 +77,12 @@ struct pasemi_mac { struct pasemi_mac_rxring *rx; unsigned long tx_irq; unsigned long rx_irq; + int link; + int speed; + int duplex; unsigned int msg_enable; + char phy_id[BUS_ID_SIZE]; }; /* Software status descriptor (desc_info) */ -- cgit v1.2.3 From a5fd22ebc71eecb7b61e542d34ac50a417b3031b Mon Sep 17 00:00:00 2001 From: Olof Johansson Date: Tue, 8 May 2007 00:48:02 -0500 Subject: pasemi_mac: Use local-mac-address instead of mac-address if available Use local-mac-address in the device tree instead. Fall back to mac-address for older firmware. Signed-off-by: Olof Johansson Signed-off-by: Jeff Garzik --- drivers/net/pasemi_mac.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) (limited to 'drivers/net') diff --git a/drivers/net/pasemi_mac.c b/drivers/net/pasemi_mac.c index 78b127c404e..b8f976bd60f 100644 --- a/drivers/net/pasemi_mac.c +++ b/drivers/net/pasemi_mac.c @@ -94,7 +94,12 @@ static int pasemi_get_mac_addr(struct pasemi_mac *mac) return -ENOENT; } - maddr = get_property(dn, "mac-address", NULL); + maddr = get_property(dn, "local-mac-address", NULL); + + /* Fall back to mac-address for older firmware */ + if (maddr == NULL) + maddr = get_property(dn, "mac-address", NULL); + if (maddr == NULL) { dev_warn(&pdev->dev, "no mac address in device tree, not configuring\n"); -- cgit v1.2.3 From e824f7836de25b1c2f659a2412d32227f1f68bcb Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Tue, 8 May 2007 02:32:17 -0400 Subject: [netdrvr] atl1: fix build We need linux/pci.h. Signed-off-by: Jeff Garzik --- drivers/net/atl1/atl1_param.c | 1 + 1 file changed, 1 insertion(+) (limited to 'drivers/net') diff --git a/drivers/net/atl1/atl1_param.c b/drivers/net/atl1/atl1_param.c index 324f9f0ece9..4246bb9bd50 100644 --- a/drivers/net/atl1/atl1_param.c +++ b/drivers/net/atl1/atl1_param.c @@ -23,6 +23,7 @@ #include #include +#include #include "atl1.h" /* -- cgit v1.2.3