From: TheNop <TheNop@gmx.net>
To: linux-mips@linux-mips.org
Subject: Re: Titan ethernet driver broken
Date: Thu, 18 Nov 2004 23:17:26 +0100 [thread overview]
Message-ID: <419D1F76.6010603@gmx.net> (raw)
In-Reply-To: <419D1A2D.5000009@gmx.net>
[-- Attachment #1: Type: text/plain, Size: 264 bytes --]
TheNop wrote:
> Manish Lachwani wrote:
>
>> Hello !
>>
>> Can you please send the diffs using "diff -u" ? It would make the
>> reading easy
>>
>> Thanks
>> Manish Lachwani
>>
>>
>>
> For sure.
>
> Best regards
> TheNop
>
Ups, something went wrong.
Next try.
CU
[-- Attachment #2: module.h.diff --]
[-- Type: text/plain, Size: 5116 bytes --]
--- linux/include/linux/module.h 2004-11-15 12:49:39.000000000 +0100
+++ linux_2_6_8_1/include/linux/module.h 2004-06-28 23:04:16.000000000 +0200
@@ -44,20 +44,6 @@
char name[MODULE_NAME_LEN];
};
-struct module;
-
-struct module_attribute {
- struct attribute attr;
- ssize_t (*show)(struct module *, char *);
- ssize_t (*store)(struct module *, const char *, size_t count);
-};
-
-struct module_kobject
-{
- struct kobject kobj;
- struct module *mod;
-};
-
/* These are either module local, or the kernel's dummy ones. */
extern int init_module(void);
extern void cleanup_module(void);
@@ -73,8 +59,6 @@
struct exception_table_entry *finish);
void sort_main_extable(void);
-extern struct subsystem module_subsys;
-
#ifdef MODULE
#define ___module_cat(a,b) __mod_ ## a ## b
#define __module_cat(a,b) ___module_cat(a,b)
@@ -157,9 +141,11 @@
customizations, eg "rh3" or "rusty1".
Using this automatically adds a checksum of the .c files and the
- local headers in "srcversion".
+ local headers to the end. Use MODULE_VERSION("") if you want just
+ this. Macro includes room for this.
*/
-#define MODULE_VERSION(_version) MODULE_INFO(version, _version)
+#define MODULE_VERSION(_version) \
+ MODULE_INFO(version, _version "\0xxxxxxxxxxxxxxxxxxxxxxxx")
/* Given an address, look for it in the exception tables */
const struct exception_table_entry *search_exception_tables(unsigned long add);
@@ -222,6 +208,23 @@
MODULE_STATE_GOING,
};
+/* sysfs stuff */
+struct module_attribute
+{
+ struct attribute attr;
+ struct kernel_param *param;
+};
+
+struct module_kobject
+{
+ /* Everyone should have one of these. */
+ struct kobject kobj;
+
+ /* We always have refcnt, we may have others from module_param(). */
+ unsigned int num_attributes;
+ struct module_attribute attr[0];
+};
+
/* Similar stuff for section attributes. */
#define MODULE_SECT_NAME_LEN 32
struct module_sect_attr
@@ -237,7 +240,6 @@
struct module_sect_attr attrs[0];
};
-struct param_kobject;
struct module
{
@@ -251,7 +253,6 @@
/* Sysfs stuff. */
struct module_kobject *mkobj;
- struct param_kobject *params_kobject;
/* Exported symbols */
const struct kernel_symbol *syms;
@@ -303,6 +304,9 @@
/* Destruction function. */
void (*exit)(void);
+
+ /* Fake kernel param for refcnt. */
+ struct kernel_param refcnt_param;
#endif
#ifdef CONFIG_KALLSYMS
@@ -441,11 +445,6 @@
int unregister_module_notifier(struct notifier_block * nb);
extern void print_modules(void);
-
-struct device_driver;
-void module_add_driver(struct module *, struct device_driver *);
-void module_remove_driver(struct device_driver *);
-
#else /* !CONFIG_MODULES... */
#define EXPORT_SYMBOL(sym)
#define EXPORT_SYMBOL_GPL(sym)
@@ -535,18 +534,6 @@
static inline void print_modules(void)
{
}
-
-struct device_driver;
-struct module;
-
-static inline void module_add_driver(struct module *module, struct device_driver *driver)
-{
-}
-
-static inline void module_remove_driver(struct device_driver *driver)
-{
-}
-
#endif /* CONFIG_MODULES */
#define symbol_request(x) try_then_request_module(symbol_get(x), "symbol:" #x)
@@ -558,27 +545,45 @@
char type[64-sizeof(void *)];
void *addr;
};
-
-static inline void __deprecated MODULE_PARM_(void) { }
#ifdef MODULE
/* DEPRECATED: Do not use. */
#define MODULE_PARM(var,type) \
struct obsolete_modparm __parm_##var __attribute__((section("__obsparm"))) = \
-{ __stringify(var), type, &MODULE_PARM_ };
+{ __stringify(var), type };
+
+static inline void __deprecated MOD_INC_USE_COUNT(struct module *module)
+{
+ __unsafe(module);
+
+#if defined(CONFIG_MODULE_UNLOAD) && defined(MODULE)
+ local_inc(&module->ref[get_cpu()].count);
+ put_cpu();
+#else
+ (void)try_module_get(module);
+#endif
+}
+
+static inline void __deprecated MOD_DEC_USE_COUNT(struct module *module)
+{
+ module_put(module);
+}
+
+#define MOD_INC_USE_COUNT MOD_INC_USE_COUNT(THIS_MODULE)
+#define MOD_DEC_USE_COUNT MOD_DEC_USE_COUNT(THIS_MODULE)
#else
-#define MODULE_PARM(var,type) static void __attribute__((__unused__)) *__parm_##var = &MODULE_PARM_;
+#define MODULE_PARM(var,type)
+#define MOD_INC_USE_COUNT do { } while (0)
+#define MOD_DEC_USE_COUNT do { } while (0)
#endif
#define __MODULE_STRING(x) __stringify(x)
/* Use symbol_get and symbol_put instead. You'll thank me. */
#define HAVE_INTER_MODULE
-extern void __deprecated inter_module_register(const char *,
- struct module *, const void *);
-extern void __deprecated inter_module_unregister(const char *);
-extern const void * __deprecated inter_module_get(const char *);
-extern const void * __deprecated inter_module_get_request(const char *,
- const char *);
-extern void __deprecated inter_module_put(const char *);
+extern void inter_module_register(const char *, struct module *, const void *);
+extern void inter_module_unregister(const char *);
+extern const void *inter_module_get(const char *);
+extern const void *inter_module_get_request(const char *, const char *);
+extern void inter_module_put(const char *);
#endif /* _LINUX_MODULE_H */
[-- Attachment #3: titan_ge.c.diff --]
[-- Type: text/plain, Size: 19294 bytes --]
--- linux/drivers/net/titan_ge.c 2004-11-17 04:08:25.000000000 +0100
+++ linux_2_6_8_1/drivers/net/titan_ge.c 2004-08-19 22:31:47.000000000 +0200
@@ -47,10 +47,13 @@
*/
#include <linux/config.h>
-#include <linux/dma-mapping.h>
+#include <linux/version.h>
#include <linux/module.h>
#include <linux/kernel.h>
+#include <linux/config.h>
#include <linux/sched.h>
+#include <linux/ptrace.h>
+#include <linux/fcntl.h>
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
@@ -59,6 +62,7 @@
#include <linux/ip.h>
#include <linux/init.h>
#include <linux/in.h>
+#include <linux/pci.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -95,6 +99,7 @@
static int titan_ge_open(struct net_device *);
static int titan_ge_start_xmit(struct sk_buff *, struct net_device *);
static int titan_ge_stop(struct net_device *);
+static int titan_ge_set_mac_address(struct net_device *, void *);
static unsigned long titan_ge_tx_coal(unsigned long, int);
@@ -103,6 +108,7 @@
static int titan_ge_rx_task(struct net_device *, titan_ge_port_info *);
static int titan_ge_port_start(struct net_device *, titan_ge_port_info *);
+static int titan_ge_init(int);
static int titan_ge_return_tx_desc(titan_ge_port_info *, int);
/*
@@ -117,20 +123,18 @@
*/
static unsigned int oom_flag;
+#ifdef TITAN_RX_NAPI
static int titan_ge_poll(struct net_device *netdev, int *budget);
+#endif
static int titan_ge_receive_queue(struct net_device *, unsigned int);
-static struct platform_device *titan_ge_device[3];
-
/* MAC Address */
extern unsigned char titan_ge_mac_addr_base[6];
unsigned long titan_ge_base;
static unsigned long titan_ge_sram;
-static char titan_string[] = "titan";
-
/*
* The Titan GE has two alignment requirements:
* -> skb->data to be cacheline aligned (32 byte)
@@ -448,6 +452,7 @@
#endif
titan_ge_free_tx_queue(titan_ge_eth);
+#ifdef TITAN_RX_NAPI
/* Handle the Rx next */
#ifdef CONFIG_SMP
if ( (eth_int_cause1 & 0x10101) ||
@@ -465,16 +470,17 @@
if (port_num == 1)
ack &= ~(0x300);
- if (port_num == 2)
- ack &= ~(0x30000);
-
/* Interrupts have been disabled */
TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, ack);
__netif_rx_schedule(netdev);
}
}
+#else
+ titan_ge_free_tx_queue(titan_ge_eth);
+ titan_ge_receive_queue(netdev, 0);
+#endif
/* Handle error interrupts */
if (eth_int_cause_error && (eth_int_cause_error != 0x2)) {
printk(KERN_ERR
@@ -609,21 +615,20 @@
static int titan_ge_rx_return_buff(titan_ge_port_info * titan_ge_port,
struct sk_buff *skb)
{
- struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev;
- volatile titan_ge_rx_desc *rx_desc;
int rx_used_desc;
+ volatile titan_ge_rx_desc *rx_desc;
rx_used_desc = titan_ge_port->rx_used_desc_q;
rx_desc = &(titan_ge_port->rx_desc_area[rx_used_desc]);
#ifdef TITAN_GE_JUMBO_FRAMES
rx_desc->buffer_addr =
- dma_map_single(device, skb->data, TITAN_GE_JUMBO_BUFSIZE - 2,
- DMA_FROM_DEVICE);
+ pci_map_single(0, skb->data, TITAN_GE_JUMBO_BUFSIZE - 2,
+ PCI_DMA_FROMDEVICE);
#else
rx_desc->buffer_addr =
- dma_map_single(device, skb->data, TITAN_GE_STD_BUFSIZE - 2,
- DMA_FROM_DEVICE);
+ pci_map_single(0, skb->data, TITAN_GE_STD_BUFSIZE - 2,
+ PCI_DMA_FROMDEVICE);
#endif
titan_ge_port->rx_skb[rx_used_desc] = skb;
@@ -720,7 +725,6 @@
volatile unsigned long reg_data, reg_data1;
int port_num = titan_port->port_num;
int count = 0;
- unsigned long reg_data_1;
if (config_done == 0) {
reg_data = TITAN_GE_READ(0x0004);
@@ -734,9 +738,11 @@
reg_data = TITAN_GE_READ(TITAN_GE_TSB_CTRL_1);
reg_data |= 0x00000700;
reg_data &= ~(0x00800000); /* Fencing */
-
+#ifdef TITAN_RX_NAPI
TITAN_GE_WRITE(0x000c, 0x00001100);
-
+#else
+ TITAN_GE_WRITE(0x000c, 0x00000100); /* No WCIMODE */
+#endif
TITAN_GE_WRITE(TITAN_GE_TSB_CTRL_1, reg_data);
/* Set the CPU Resource Limit register */
@@ -746,8 +752,10 @@
TITAN_GE_WRITE(0x0068, 0x4);
}
+#ifdef TITAN_RX_NAPI
titan_port->tx_threshold = 0;
titan_port->rx_threshold = 0;
+#endif
/* We need to write the descriptors for Tx and Rx */
TITAN_GE_WRITE((TITAN_GE_CHANNEL0_TX_DESC + (port_num << 8)),
@@ -902,52 +910,6 @@
TITAN_GE_WRITE(0x494c, reg_data);
}
- /*
- * Titan 1.2 revision does support port #2
- */
- if (port_num == 2) {
- /*
- * Put the descriptors in the SRAM
- */
- reg_data = TITAN_GE_READ(0x48a0);
-
- reg_data |= 0x100000;
- reg_data |= (0xff << 10) | (2*(0xff + 1));
-
- TITAN_GE_WRITE(0x48a0, reg_data);
- /*
- * BAV2,BAV and DAV settings for the Rx FIFO
- */
- reg_data1 = TITAN_GE_READ(0x48a4);
- reg_data1 |= ( (0x10 << 20) | (0x10 << 10) | 0x1);
- TITAN_GE_WRITE(0x48a4, reg_data1);
-
- reg_data &= ~(0x00100000);
- reg_data |= 0x200000;
-
- TITAN_GE_WRITE(0x48a0, reg_data);
-
- reg_data = TITAN_GE_READ(0x4958);
- reg_data |= 0x100000;
-
- TITAN_GE_WRITE(0x4958, reg_data);
- reg_data |= (0xff << 10) | (2*(0xff + 1));
- TITAN_GE_WRITE(0x4958, reg_data);
-
- /*
- * BAV2, BAV and DAV settings for the Tx FIFO
- */
- reg_data1 = TITAN_GE_READ(0x495c);
- reg_data1 = ( (0x1 << 20) | (0x1 << 10) | 0x10);
-
- TITAN_GE_WRITE(0x495c, reg_data1);
-
- reg_data &= ~(0x00100000);
- reg_data |= 0x200000;
-
- TITAN_GE_WRITE(0x4958, reg_data);
- }
-
if (port_num == 2) {
reg_data = TITAN_GE_READ(0x48a0);
@@ -992,28 +954,6 @@
* Step 3: TRTG block enable
*/
reg_data = TITAN_GE_READ(TITAN_GE_TRTG_CONFIG + (port_num << 12));
-
- /*
- * This is the 1.2 revision of the chip. It has fix for the
- * IP header alignment. Now, the IP header begins at an
- * aligned address and this wont need an extra copy in the
- * driver. This performance drawback existed in the previous
- * versions of the silicon
- */
- reg_data_1 = TITAN_GE_READ(0x103c + (port_num << 12));
- reg_data_1 |= 0x40000000;
- TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
-
- reg_data_1 |= 0x04000000;
- TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
-
- mdelay(5);
-
- reg_data_1 &= ~(0x04000000);
- TITAN_GE_WRITE((0x103c + (port_num << 12)), reg_data_1);
-
- mdelay(5);
-
reg_data |= 0x0001;
TITAN_GE_WRITE((TITAN_GE_TRTG_CONFIG + (port_num << 12)), reg_data);
@@ -1071,9 +1011,6 @@
reg_data1 |= 0x300;
}
- if (port_num == 2)
- reg_data1 |= 0x30000;
-
TITAN_GE_WRITE(TITAN_GE_INTR_XDMA_IE, reg_data1);
TITAN_GE_WRITE(0x003c, 0x300);
@@ -1104,15 +1041,15 @@
static void titan_ge_tx_queue(titan_ge_port_info * titan_ge_eth,
struct sk_buff * skb)
{
- struct device *device = &titan_ge_device[titan_ge_eth->port_num]->dev;
- unsigned int curr_desc = titan_ge_eth->tx_curr_desc_q;
volatile titan_ge_tx_desc *tx_curr;
int port_num = titan_ge_eth->port_num;
+ unsigned int curr_desc =
+ titan_ge_eth->tx_curr_desc_q;
tx_curr = &(titan_ge_eth->tx_desc_area[curr_desc]);
tx_curr->buffer_addr =
- dma_map_single(device, skb->data, skb_headlen(skb),
- DMA_TO_DEVICE);
+ pci_map_single(0, skb->data, skb_headlen(skb),
+ PCI_DMA_TODEVICE);
titan_ge_eth->tx_skb[curr_desc] = (struct sk_buff *) skb;
tx_curr->buffer_len = skb_headlen(skb);
@@ -1131,6 +1068,19 @@
&titan_ge_eth->tx_desc_area[titan_ge_eth->tx_curr_desc_q]);
}
+#ifndef TITAN_RX_NAPI
+/*
+ * Coalescing for the Rx path
+ */
+static unsigned long titan_ge_rx_coal(unsigned long delay, int port)
+{
+ TITAN_GE_WRITE(TITAN_GE_INT_COALESCING, delay);
+ TITAN_GE_WRITE(0x5038, delay);
+
+ return delay;
+}
+#endif
+
/*
* Actually does the open of the Ethernet device
*/
@@ -1138,7 +1088,6 @@
{
titan_ge_port_info *titan_ge_eth = netdev_priv(netdev);
unsigned int port_num = titan_ge_eth->port_num;
- struct device *device = &titan_ge_device[port_num]->dev;
unsigned int size, phy_reg;
unsigned long reg_data;
int err = 0;
@@ -1187,13 +1136,6 @@
titan_ge_eth->tx_dma = TITAN_SRAM_BASE + 0x100;
}
- if (port_num == 2) {
- titan_ge_eth->tx_desc_area =
- (titan_ge_tx_desc *) (titan_ge_sram + 0x200);
-
- titan_ge_eth->tx_dma = TITAN_SRAM_BASE + 0x200;
- }
-
if (!titan_ge_eth->tx_desc_area) {
printk(KERN_ERR
"%s: Cannot allocate Tx Ring (size %d bytes) for port %d\n",
@@ -1228,12 +1170,6 @@
titan_ge_eth->rx_dma = TITAN_SRAM_BASE + 0x1100;
}
- if (port_num == 2) {
- titan_ge_eth->rx_desc_area =
- (titan_ge_rx_desc *)(titan_ge_sram + 0x1200);
- titan_ge_eth->rx_dma = TITAN_SRAM_BASE + 0x1200;
- }
-
if (!titan_ge_eth->rx_desc_area) {
printk(KERN_ERR
"%s: Cannot allocate Rx Ring (size %d bytes)\n",
@@ -1243,7 +1179,7 @@
"%s: Freeing previously allocated TX queues...",
netdev->name);
- dma_free_coherent(device, titan_ge_eth->tx_desc_area_size,
+ pci_free_consistent(0, titan_ge_eth->tx_desc_area_size,
(void *) titan_ge_eth->tx_desc_area,
titan_ge_eth->tx_dma);
@@ -1276,7 +1212,19 @@
* (8 x 64 nanoseconds) to determine when an interrupt should
* be sent to the CPU.
*/
+#ifndef TITAN_RX_NAPI
+ /*
+ * If NAPI is turned on, we disable Rx interrupts
+ * completely. So, we dont need coalescing then. Tx side
+ * coalescing set to very high value. Maybe, disable
+ * Tx side interrupts completely
+ */
+ if (TITAN_GE_RX_COAL) {
+ titan_ge_eth->rx_int_coal =
+ titan_ge_rx_coal(TITAN_GE_RX_COAL, port_num);
+ }
+#endif
if (TITAN_GE_TX_COAL) {
titan_ge_eth->tx_int_coal =
titan_ge_tx_coal(TITAN_GE_TX_COAL, port_num);
@@ -1406,6 +1354,45 @@
}
/*
+ * Do the slowpath route. This route is kicked off
+ * when the IP header is misaligned. Grrr ..
+ */
+static int titan_ge_slowpath(struct sk_buff *skb,
+ titan_ge_packet *packet,
+ struct net_device *netdev)
+{
+ struct sk_buff *copy_skb;
+
+ copy_skb = dev_alloc_skb(packet->len + 2);
+
+ if (!copy_skb) {
+ dev_kfree_skb_any(packet->skb);
+ return -1;
+ }
+
+ copy_skb->dev = netdev;
+ skb_reserve(copy_skb, 2);
+ skb_put(copy_skb, packet->len);
+
+ memcpy(copy_skb->data, skb->data, packet->len);
+
+ /* Titan supports Rx checksum offload */
+ copy_skb->ip_summed = CHECKSUM_HW;
+ copy_skb->csum = packet->checksum;
+
+ copy_skb->protocol = eth_type_trans(copy_skb, netdev);
+
+ dev_kfree_skb_any(packet->skb);
+#ifdef TITAN_RX_NAPI
+ netif_receive_skb(copy_skb);
+#else
+ netif_rx(copy_skb);
+#endif
+
+ return 0;
+}
+
+/*
* Threshold beyond which we do the cleaning of
* Tx queue and new allocation for the Rx
* queue
@@ -1434,10 +1421,11 @@
titan_ge_eth->rx_ring_skbs--;
+#ifdef TITAN_RX_NAPI
if (--titan_ge_eth->rx_work_limit < 0)
break;
received_packets++;
-
+#endif
stats->rx_packets++;
stats->rx_bytes += packet.len;
@@ -1456,36 +1444,41 @@
* idea is to cut down the number of checks and improve
* the fastpath.
*/
+ skb_put(skb, packet.len);
- skb_put(skb, packet.len - 2);
-
- /*
- * Increment data pointer by two since thats where
- * the MAC starts
- */
- skb_reserve(skb, 2);
- skb->protocol = eth_type_trans(skb, netdev);
- netif_receive_skb(skb);
+ if (titan_ge_slowpath(skb, &packet, netdev) < 0)
+ goto out_next;
+#ifdef TITAN_RX_NAPI
if (titan_ge_eth->rx_threshold > RX_THRESHOLD) {
ack = titan_ge_rx_task(netdev, titan_ge_eth);
TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);
titan_ge_eth->rx_threshold = 0;
} else
titan_ge_eth->rx_threshold++;
+#else
+ ack = titan_ge_rx_task(netdev, titan_ge_eth);
+ TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);
+#endif
+out_next:
+
+#ifdef TITAN_RX_NAPI
if (titan_ge_eth->tx_threshold > TX_THRESHOLD) {
titan_ge_eth->tx_threshold = 0;
titan_ge_free_tx_queue(titan_ge_eth);
}
else
titan_ge_eth->tx_threshold++;
+#endif
}
return received_packets;
}
+#ifdef TITAN_RX_NAPI
+
/*
* Enable the Rx side interrupts
*/
@@ -1587,6 +1580,7 @@
return 0;
}
+#endif
/*
* Close the network device
@@ -1598,6 +1592,7 @@
spin_lock_irq(&(titan_ge_eth->lock));
titan_ge_eth_stop(netdev);
free_irq(netdev->irq, netdev);
+ MOD_DEC_USE_COUNT;
spin_unlock_irq(&titan_ge_eth->lock);
return TITAN_OK;
@@ -1643,8 +1638,7 @@
titan_ge_eth->tx_ring_skbs);
#ifndef TITAN_RX_RING_IN_SRAM
- dma_free_coherent(&titan_ge_device[port_num]->dev,
- titan_ge_eth->tx_desc_area_size,
+ pci_free_consistent(0, titan_ge_eth->tx_desc_area_size,
(void *) titan_ge_eth->tx_desc_area,
titan_ge_eth->tx_dma);
#endif
@@ -1690,8 +1684,7 @@
titan_ge_eth->rx_ring_skbs);
#ifndef TITAN_RX_RING_IN_SRAM
- dma_free_coherent(&titan_ge_device[port_num]->dev,
- titan_ge_eth->rx_desc_area_size,
+ pci_free_consistent(0, titan_ge_eth->rx_desc_area_size,
(void *) titan_ge_eth->rx_desc_area,
titan_ge_eth->rx_dma);
#endif
@@ -1752,22 +1745,21 @@
((p_addr[3] << 8) | p_addr[2]));
TITAN_GE_WRITE((TITAN_GE_RMAC_STATION_LOW + (port_num << 12)),
((p_addr[1] << 8) | p_addr[0]));
+
+ return;
}
/*
* Set the MAC address of the Ethernet device
*/
-static int titan_ge_set_mac_address(struct net_device *dev, void *addr)
+int titan_ge_set_mac_address(struct net_device *netdev, void *addr)
{
- titan_ge_port_info *tp = netdev_priv(dev);
- struct sockaddr *sa = addr;
-
- memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
+ int i;
- spin_lock_irq(&tp->lock);
- titan_ge_update_mac_address(dev);
- spin_unlock_irq(&tp->lock);
+ for (i = 0; i < 6; i++)
+ netdev->dev_addr[i] = ((unsigned char *) addr)[i + 2];
+ titan_ge_update_mac_address(netdev);
return 0;
}
@@ -1782,6 +1774,65 @@
}
/*
+ * Register the Titan GE with the kernel
+ */
+static int __init titan_ge_init_module(void)
+{
+ unsigned int version, device;
+
+ printk(KERN_NOTICE
+ "PMC-Sierra TITAN 10/100/1000 Ethernet Driver \n");
+
+ titan_ge_base = (unsigned long) ioremap(TITAN_GE_BASE, TITAN_GE_SIZE);
+ if (!titan_ge_base) {
+ printk("Mapping Titan GE failed\n");
+ goto out;
+ }
+
+ device = TITAN_GE_READ(TITAN_GE_DEVICE_ID);
+ version = (device & 0x000f0000) >> 16;
+ device &= 0x0000ffff;
+
+ printk(KERN_NOTICE "Device Id : %x, Version : %x \n", device, version);
+
+#ifdef TITAN_RX_RING_IN_SRAM
+ titan_ge_sram = (unsigned long) ioremap(TITAN_SRAM_BASE,
+ TITAN_SRAM_SIZE);
+ if (!titan_ge_sram) {
+ printk("Mapping Titan SRAM failed\n");
+ goto out_unmap_ge;
+ }
+#endif
+
+ /* Register only one port */
+ if (titan_ge_init(0))
+ printk(KERN_ERR
+ "Error registering the TITAN Ethernet driver"
+ "for port 0 \n");
+
+ if (titan_ge_init(1))
+ printk(KERN_ERR "Error registering the TITAN Ethernet"
+ "driver for port 1\n");
+
+ return 0;
+
+out_unmap_ge:
+ iounmap((void *)titan_ge_base);
+
+out:
+ return -ENOMEM;
+}
+
+/*
+ * Unregister the Titan GE from the kernel
+ */
+static void __init titan_ge_cleanup_module(void)
+{
+ iounmap((void *)titan_ge_sram);
+ iounmap((void *)titan_ge_base);
+}
+
+/*
* Initialize the Rx descriptor ring for the Titan Ge
*/
static int titan_ge_init_rx_desc_ring(titan_ge_port_info * titan_eth_port,
@@ -1875,11 +1926,10 @@
/*
* Initialize the device as an Ethernet device
*/
-static int __init titan_ge_probe(struct device *device)
+static int titan_ge_init(int port)
{
titan_ge_port_info *titan_ge_eth;
struct net_device *netdev;
- int port = to_platform_device(device)->id;
int err;
netdev = alloc_etherdev(sizeof(titan_ge_port_info));
@@ -1899,10 +1949,11 @@
netdev->tx_timeout = titan_ge_tx_timeout;
netdev->watchdog_timeo = 2 * HZ;
+#ifdef TITAN_RX_NAPI
/* Set these to very high values */
netdev->poll = titan_ge_poll;
netdev->weight = 64;
-
+#endif
netdev->tx_queue_len = TITAN_GE_TX_QUEUE;
netif_carrier_off(netdev);
netdev->base_addr = 0;
@@ -1936,7 +1987,11 @@
netdev->dev_addr[3], netdev->dev_addr[4],
netdev->dev_addr[5]);
+#ifdef TITAN_RX_NAPI
printk(KERN_NOTICE "Rx NAPI supported, Tx Coalescing ON \n");
+#else
+ printk(KERN_NOTICE "Rx and Tx Coalescing ON \n");
+#endif
return 0;
@@ -2013,122 +2068,6 @@
return delay;
}
-static struct device_driver titan_soc_driver = {
- .name = titan_string,
- .bus = &platform_bus_type,
- .probe = titan_ge_probe,
- .remove = __devexit_p(titan_device_remove),
-};
-
-static void titan_platform_release (struct device *device)
-{
- struct platform_device *pldev;
-
- /* free device */
- pldev = to_platform_device (device);
- kfree (pldev);
-}
-
-/*
- * Register the Titan GE with the kernel
- */
-static int __init titan_ge_init_module(void)
-{
- struct platform_device *pldev;
- unsigned int version, device;
- int i;
-
- printk(KERN_NOTICE
- "PMC-Sierra TITAN 10/100/1000 Ethernet Driver \n");
-
- titan_ge_base = (unsigned long) ioremap(TITAN_GE_BASE, TITAN_GE_SIZE);
- if (!titan_ge_base) {
- printk("Mapping Titan GE failed\n");
- goto out;
- }
-
- device = TITAN_GE_READ(TITAN_GE_DEVICE_ID);
- version = (device & 0x000f0000) >> 16;
- device &= 0x0000ffff;
-
- printk(KERN_NOTICE "Device Id : %x, Version : %x \n", device, version);
-
-#ifdef TITAN_RX_RING_IN_SRAM
- titan_ge_sram = (unsigned long) ioremap(TITAN_SRAM_BASE,
- TITAN_SRAM_SIZE);
- if (!titan_ge_sram) {
- printk("Mapping Titan SRAM failed\n");
- goto out_unmap_ge;
- }
-#endif
-
- if (driver_register(&titan_soc_driver)) {
- printk(KERN_ERR "Driver registration failed\n");
- goto out_unmap_sram;
- }
-
- for (i = 0; i < 3; i++) {
- titan_ge_device[i] = NULL;
-
- if (!(pldev = kmalloc (sizeof (*pldev), GFP_KERNEL)))
- continue;
-
- memset (pldev, 0, sizeof (*pldev));
- pldev->name = titan_string;
- pldev->id = i;
- pldev->dev.release = titan_platform_release;
- titan_ge_device[i] = pldev;
-
- if (platform_device_register (pldev)) {
- kfree (pldev);
- titan_ge_device[i] = NULL;
- continue;
- }
-
- if (!pldev->dev.driver) {
- /*
- * The driver was not bound to this device, there was
- * no hardware at this address. Unregister it, as the
- * release fuction will take care of freeing the
- * allocated structure
- */
- titan_ge_device[i] = NULL;
- platform_device_unregister (pldev);
- }
- }
-
- return 0;
-
-out_unmap_sram:
- iounmap((void *)titan_ge_sram);
-
-out_unmap_ge:
- iounmap((void *)titan_ge_base);
-
-out:
- return -ENOMEM;
-}
-
-/*
- * Unregister the Titan GE from the kernel
- */
-static void __exit titan_ge_cleanup_module(void)
-{
- int i;
-
- driver_unregister(&titan_soc_driver);
-
- for (i = 0; i < 3; i++) {
- if (titan_ge_device[i]) {
- platform_device_unregister (titan_ge_device[i]);
- titan_ge_device[i] = NULL;
- }
- }
-
- iounmap((void *)titan_ge_sram);
- iounmap((void *)titan_ge_base);
-}
-
MODULE_AUTHOR("Manish Lachwani <lachwani@pmc-sierra.com>");
MODULE_DESCRIPTION("Titan GE Ethernet driver");
MODULE_LICENSE("GPL");
[-- Attachment #4: titan_ge.h.diff --]
[-- Type: text/plain, Size: 348 bytes --]
--- linux/drivers/net/titan_ge.h 2004-10-26 03:46:16.000000000 +0200
+++ linux_2_6_8_1/drivers/net/titan_ge.h 2004-08-19 22:31:47.000000000 +0200
@@ -101,6 +101,9 @@
/* Debugging info only */
#undef TITAN_DEBUG
+/* Support for Rx side NAPI */
+#define TITAN_RX_NAPI
+
/* Keep the rings in the Titan's SSRAM */
#define TITAN_RX_RING_IN_SRAM
next prev parent reply other threads:[~2004-11-18 22:11 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2004-11-18 20:19 Titan ethernet driver broken TheNop
2004-11-18 20:23 ` Manish Lachwani
2004-11-18 21:41 ` TheNop
2004-11-18 21:42 ` Manish Lachwani
2004-11-18 21:54 ` TheNop
2004-11-18 22:17 ` TheNop [this message]
2004-11-18 22:23 ` Manish Lachwani
2004-11-18 22:43 ` TheNop
2004-11-18 23:43 ` Manish Lachwani
2004-11-20 9:54 ` Ralf Baechle
2004-11-21 7:26 ` Manish Lachwani
2004-11-19 17:32 ` Manish Lachwani
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=419D1F76.6010603@gmx.net \
--to=thenop@gmx.net \
--cc=linux-mips@linux-mips.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox