* Titan ethernet driver broken
@ 2004-11-18 20:19 TheNop
2004-11-18 20:23 ` Manish Lachwani
0 siblings, 1 reply; 12+ messages in thread
From: TheNop @ 2004-11-18 20:19 UTC (permalink / raw)
To: linux-mips
Hello,
using DHCP support on the yosemite target with the current sources did
not work anymore.
The DHCP request timed out.
Using the sources from cvs lable linux_2_6_8_1 for the titan ethernet
driver works around this problem.
Best regards
TheNop
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
2004-11-18 20:19 Titan ethernet driver broken TheNop
@ 2004-11-18 20:23 ` Manish Lachwani
2004-11-18 21:41 ` TheNop
0 siblings, 1 reply; 12+ messages in thread
From: Manish Lachwani @ 2004-11-18 20:23 UTC (permalink / raw)
To: TheNop; +Cc: linux-mips
TheNop wrote:
> Hello,
>
> using DHCP support on the yosemite target with the current sources did
> not work anymore.
> The DHCP request timed out.
> Using the sources from cvs lable linux_2_6_8_1 for the titan ethernet
> driver works around this problem.
>
> Best regards
> TheNop
>
>
>
Hello !
Can you send the diff between the titan_ge (both .c and .h files) driver
version in linux_2_6_8_1 and the latest driver sources?
Thanks
Manish Lachwani
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
2004-11-18 20:23 ` Manish Lachwani
@ 2004-11-18 21:41 ` TheNop
2004-11-18 21:42 ` Manish Lachwani
0 siblings, 1 reply; 12+ messages in thread
From: TheNop @ 2004-11-18 21:41 UTC (permalink / raw)
To: linux-mips
[-- Attachment #1: Type: text/plain, Size: 610 bytes --]
Manish Lachwani wrote:
> TheNop wrote:
>
>> Hello,
>>
>> using DHCP support on the yosemite target with the current sources
>> did not work anymore.
>> The DHCP request timed out.
>> Using the sources from cvs lable linux_2_6_8_1 for the titan ethernet
>> driver works around this problem.
>>
>> Best regards
>> TheNop
>>
>>
>>
> Hello !
>
> Can you send the diff between the titan_ge (both .c and .h files)
> driver version in linux_2_6_8_1 and the latest driver sources?
>
> Thanks
> Manish Lachwani
>
>
>
Hi Manish,
here are the diffs. You also need moduls.h from linux_2_6_8_1.
Best regards
TheNop
[-- Attachment #2: module.h.diff --]
[-- Type: text/plain, Size: 3279 bytes --]
47,60d46
< 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;
< };
<
76,77d61
< extern struct subsystem module_subsys;
<
160c144,145
< local headers in "srcversion".
---
> local headers to the end. Use MODULE_VERSION("") if you want just
> this. Macro includes room for this.
162c147,148
< #define MODULE_VERSION(_version) MODULE_INFO(version, _version)
---
> #define MODULE_VERSION(_version) \
> MODULE_INFO(version, _version "\0xxxxxxxxxxxxxxxxxxxxxxxx")
224a211,227
> /* 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];
> };
>
240d242
< struct param_kobject;
254d255
< struct param_kobject *params_kobject;
305a307,309
>
> /* Fake kernel param for refcnt. */
> struct kernel_param refcnt_param;
444,448d447
<
< struct device_driver;
< void module_add_driver(struct module *, struct device_driver *);
< void module_remove_driver(struct device_driver *);
<
538,549d536
<
< 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)
< {
< }
<
561,562d547
<
< static inline void __deprecated MODULE_PARM_(void) { }
567c552,572
< { __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)
569c574,576
< #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)
576,582c583,587
< 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 *);
[-- Attachment #3: titan_ge.c.diff --]
[-- Type: text/plain, Size: 12610 bytes --]
50c50
< #include <linux/dma-mapping.h>
---
> #include <linux/version.h>
52a53
> #include <linux/config.h>
53a55,56
> #include <linux/ptrace.h>
> #include <linux/fcntl.h>
61a65
> #include <linux/pci.h>
97a102
> static int titan_ge_set_mac_address(struct net_device *, void *);
105a111
> static int titan_ge_init(int);
119a126
> #ifdef TITAN_RX_NAPI
120a128
> #endif
124,125d131
< static struct platform_device *titan_ge_device[3];
<
132,133d137
< static char titan_string[] = "titan";
<
450a455
> #ifdef TITAN_RX_NAPI
468,470d472
< if (port_num == 2)
< ack &= ~(0x30000);
<
476a479,481
> #else
> titan_ge_free_tx_queue(titan_ge_eth);
> titan_ge_receive_queue(netdev, 0);
477a483
> #endif
612,613d617
< struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev;
< volatile titan_ge_rx_desc *rx_desc;
614a619
> volatile titan_ge_rx_desc *rx_desc;
621,622c626,627
< 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);
625,626c630,631
< 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);
723d727
< unsigned long reg_data_1;
737c741
<
---
> #ifdef TITAN_RX_NAPI
739c743,745
<
---
> #else
> TITAN_GE_WRITE(0x000c, 0x00000100); /* No WCIMODE */
> #endif
748a755
> #ifdef TITAN_RX_NAPI
750a758
> #endif
905,950d912
< /*
< * 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);
< }
<
995,1016d956
<
< /*
< * 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);
<
1074,1076d1013
< if (port_num == 2)
< reg_data1 |= 0x30000;
<
1107,1108d1043
< struct device *device = &titan_ge_device[titan_ge_eth->port_num]->dev;
< unsigned int curr_desc = titan_ge_eth->tx_curr_desc_q;
1110a1046,1047
> unsigned int curr_desc =
> titan_ge_eth->tx_curr_desc_q;
1114,1115c1051,1052
< dma_map_single(device, skb->data, skb_headlen(skb),
< DMA_TO_DEVICE);
---
> pci_map_single(0, skb->data, skb_headlen(skb),
> PCI_DMA_TODEVICE);
1133a1071,1083
> #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
>
1141d1090
< struct device *device = &titan_ge_device[port_num]->dev;
1190,1196d1138
< 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;
< }
<
1231,1236d1172
< 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;
< }
<
1246c1182
< dma_free_coherent(device, titan_ge_eth->tx_desc_area_size,
---
> pci_free_consistent(0, titan_ge_eth->tx_desc_area_size,
1278a1215,1225
> #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);
> }
1279a1227
> #endif
1408a1357,1395
> * 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;
> }
>
> /*
1436a1424
> #ifdef TITAN_RX_NAPI
1440c1428
<
---
> #endif
1458a1447
> skb_put(skb, packet.len);
1460,1468c1449,1450
< 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;
1469a1452
> #ifdef TITAN_RX_NAPI
1475a1459,1462
> #else
> ack = titan_ge_rx_task(netdev, titan_ge_eth);
> TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);
> #endif
1476a1464,1466
> out_next:
>
> #ifdef TITAN_RX_NAPI
1482a1473
> #endif
1488a1480,1481
> #ifdef TITAN_RX_NAPI
>
1589a1583
> #endif
1600a1595
> MOD_DEC_USE_COUNT;
1646,1647c1641
< 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,
1693,1694c1687
< 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,
1754a1748,1749
>
> return;
1760c1755
< 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)
1762,1765c1757
< titan_ge_port_info *tp = netdev_priv(dev);
< struct sockaddr *sa = addr;
<
< memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
---
> int i;
1767,1769c1759,1760
< 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];
1770a1762
> titan_ge_update_mac_address(netdev);
1784a1777,1835
> * 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);
> }
>
> /*
1878c1929
< static int __init titan_ge_probe(struct device *device)
---
> static int titan_ge_init(int port)
1882d1932
< int port = to_platform_device(device)->id;
1901a1952
> #ifdef TITAN_RX_NAPI
1905c1956
<
---
> #endif
1938a1990
> #ifdef TITAN_RX_NAPI
1939a1992,1994
> #else
> printk(KERN_NOTICE "Rx and Tx Coalescing ON \n");
> #endif
2016,2131d2070
< 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);
< }
<
[-- Attachment #4: titan_ge.h.diff --]
[-- Type: text/plain, Size: 72 bytes --]
103a104,106
> /* Support for Rx side NAPI */
> #define TITAN_RX_NAPI
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
2004-11-18 21:41 ` TheNop
@ 2004-11-18 21:42 ` Manish Lachwani
2004-11-18 21:54 ` TheNop
0 siblings, 1 reply; 12+ messages in thread
From: Manish Lachwani @ 2004-11-18 21:42 UTC (permalink / raw)
To: TheNop; +Cc: linux-mips
Hello !
Can you please send the diffs using "diff -u" ? It would make the
reading easy
Thanks
Manish Lachwani
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
2004-11-18 21:42 ` Manish Lachwani
@ 2004-11-18 21:54 ` TheNop
2004-11-18 22:17 ` TheNop
0 siblings, 1 reply; 12+ messages in thread
From: TheNop @ 2004-11-18 21:54 UTC (permalink / raw)
To: linux-mips
[-- Attachment #1: Type: text/plain, Size: 187 bytes --]
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
[-- Attachment #2: module.h.diff --]
[-- Type: text/plain, Size: 3279 bytes --]
47,60d46
< 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;
< };
<
76,77d61
< extern struct subsystem module_subsys;
<
160c144,145
< local headers in "srcversion".
---
> local headers to the end. Use MODULE_VERSION("") if you want just
> this. Macro includes room for this.
162c147,148
< #define MODULE_VERSION(_version) MODULE_INFO(version, _version)
---
> #define MODULE_VERSION(_version) \
> MODULE_INFO(version, _version "\0xxxxxxxxxxxxxxxxxxxxxxxx")
224a211,227
> /* 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];
> };
>
240d242
< struct param_kobject;
254d255
< struct param_kobject *params_kobject;
305a307,309
>
> /* Fake kernel param for refcnt. */
> struct kernel_param refcnt_param;
444,448d447
<
< struct device_driver;
< void module_add_driver(struct module *, struct device_driver *);
< void module_remove_driver(struct device_driver *);
<
538,549d536
<
< 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)
< {
< }
<
561,562d547
<
< static inline void __deprecated MODULE_PARM_(void) { }
567c552,572
< { __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)
569c574,576
< #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)
576,582c583,587
< 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 *);
[-- Attachment #3: titan_ge.c.diff --]
[-- Type: text/plain, Size: 12610 bytes --]
50c50
< #include <linux/dma-mapping.h>
---
> #include <linux/version.h>
52a53
> #include <linux/config.h>
53a55,56
> #include <linux/ptrace.h>
> #include <linux/fcntl.h>
61a65
> #include <linux/pci.h>
97a102
> static int titan_ge_set_mac_address(struct net_device *, void *);
105a111
> static int titan_ge_init(int);
119a126
> #ifdef TITAN_RX_NAPI
120a128
> #endif
124,125d131
< static struct platform_device *titan_ge_device[3];
<
132,133d137
< static char titan_string[] = "titan";
<
450a455
> #ifdef TITAN_RX_NAPI
468,470d472
< if (port_num == 2)
< ack &= ~(0x30000);
<
476a479,481
> #else
> titan_ge_free_tx_queue(titan_ge_eth);
> titan_ge_receive_queue(netdev, 0);
477a483
> #endif
612,613d617
< struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev;
< volatile titan_ge_rx_desc *rx_desc;
614a619
> volatile titan_ge_rx_desc *rx_desc;
621,622c626,627
< 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);
625,626c630,631
< 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);
723d727
< unsigned long reg_data_1;
737c741
<
---
> #ifdef TITAN_RX_NAPI
739c743,745
<
---
> #else
> TITAN_GE_WRITE(0x000c, 0x00000100); /* No WCIMODE */
> #endif
748a755
> #ifdef TITAN_RX_NAPI
750a758
> #endif
905,950d912
< /*
< * 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);
< }
<
995,1016d956
<
< /*
< * 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);
<
1074,1076d1013
< if (port_num == 2)
< reg_data1 |= 0x30000;
<
1107,1108d1043
< struct device *device = &titan_ge_device[titan_ge_eth->port_num]->dev;
< unsigned int curr_desc = titan_ge_eth->tx_curr_desc_q;
1110a1046,1047
> unsigned int curr_desc =
> titan_ge_eth->tx_curr_desc_q;
1114,1115c1051,1052
< dma_map_single(device, skb->data, skb_headlen(skb),
< DMA_TO_DEVICE);
---
> pci_map_single(0, skb->data, skb_headlen(skb),
> PCI_DMA_TODEVICE);
1133a1071,1083
> #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
>
1141d1090
< struct device *device = &titan_ge_device[port_num]->dev;
1190,1196d1138
< 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;
< }
<
1231,1236d1172
< 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;
< }
<
1246c1182
< dma_free_coherent(device, titan_ge_eth->tx_desc_area_size,
---
> pci_free_consistent(0, titan_ge_eth->tx_desc_area_size,
1278a1215,1225
> #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);
> }
1279a1227
> #endif
1408a1357,1395
> * 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;
> }
>
> /*
1436a1424
> #ifdef TITAN_RX_NAPI
1440c1428
<
---
> #endif
1458a1447
> skb_put(skb, packet.len);
1460,1468c1449,1450
< 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;
1469a1452
> #ifdef TITAN_RX_NAPI
1475a1459,1462
> #else
> ack = titan_ge_rx_task(netdev, titan_ge_eth);
> TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);
> #endif
1476a1464,1466
> out_next:
>
> #ifdef TITAN_RX_NAPI
1482a1473
> #endif
1488a1480,1481
> #ifdef TITAN_RX_NAPI
>
1589a1583
> #endif
1600a1595
> MOD_DEC_USE_COUNT;
1646,1647c1641
< 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,
1693,1694c1687
< 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,
1754a1748,1749
>
> return;
1760c1755
< 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)
1762,1765c1757
< titan_ge_port_info *tp = netdev_priv(dev);
< struct sockaddr *sa = addr;
<
< memcpy(dev->dev_addr, sa->sa_data, dev->addr_len);
---
> int i;
1767,1769c1759,1760
< 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];
1770a1762
> titan_ge_update_mac_address(netdev);
1784a1777,1835
> * 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);
> }
>
> /*
1878c1929
< static int __init titan_ge_probe(struct device *device)
---
> static int titan_ge_init(int port)
1882d1932
< int port = to_platform_device(device)->id;
1901a1952
> #ifdef TITAN_RX_NAPI
1905c1956
<
---
> #endif
1938a1990
> #ifdef TITAN_RX_NAPI
1939a1992,1994
> #else
> printk(KERN_NOTICE "Rx and Tx Coalescing ON \n");
> #endif
2016,2131d2070
< 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);
< }
<
[-- Attachment #4: titan_ge.h.diff --]
[-- Type: text/plain, Size: 72 bytes --]
103a104,106
> /* Support for Rx side NAPI */
> #define TITAN_RX_NAPI
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
2004-11-18 21:54 ` TheNop
@ 2004-11-18 22:17 ` TheNop
2004-11-18 22:23 ` Manish Lachwani
2004-11-19 17:32 ` Manish Lachwani
0 siblings, 2 replies; 12+ messages in thread
From: TheNop @ 2004-11-18 22:17 UTC (permalink / raw)
To: linux-mips
[-- 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
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
2004-11-18 22:17 ` TheNop
@ 2004-11-18 22:23 ` Manish Lachwani
2004-11-18 22:43 ` TheNop
2004-11-19 17:32 ` Manish Lachwani
1 sibling, 1 reply; 12+ messages in thread
From: Manish Lachwani @ 2004-11-18 22:23 UTC (permalink / raw)
To: TheNop; +Cc: linux-mips
Hello !
Thanks for sending this. I have one question regarding the Yosemite
board that you have. What is the version of the Titan chip on the board?
Is it 1.0, 1.1 or 1.2?
This is because 1.0 and 1.1 have a problem where the IP header is not
aligned on the Rx side. As a result, there was an extra copy involved in
the driver, i.e. titan_ge_slowpath. The latest version of the driver
only support Titan chip revision 1.2 in which this problem is fixed
Thanks
Manish Lachwani
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
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
0 siblings, 2 replies; 12+ messages in thread
From: TheNop @ 2004-11-18 22:43 UTC (permalink / raw)
To: linux-mips
Manish Lachwani wrote:
> Hello !
>
> Thanks for sending this. I have one question regarding the Yosemite
> board that you have. What is the version of the Titan chip on the
> board? Is it 1.0, 1.1 or 1.2?
>
> This is because 1.0 and 1.1 have a problem where the IP header is not
> aligned on the Rx side. As a result, there was an extra copy involved
> in the driver, i.e. titan_ge_slowpath. The latest version of the
> driver only support Titan chip revision 1.2 in which this problem is
> fixed
>
> Thanks
> Manish Lachwani
>
>
>
I use the chip version 1.1.
Now I have the problem, that I can not use the newest code, until 1.2
version of the chip is available.
Is it possible to make the code usable for all chip version by choosing
the version at the kernel configuration?
Best regards
TheNop
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
2004-11-18 22:43 ` TheNop
@ 2004-11-18 23:43 ` Manish Lachwani
2004-11-20 9:54 ` Ralf Baechle
1 sibling, 0 replies; 12+ messages in thread
From: Manish Lachwani @ 2004-11-18 23:43 UTC (permalink / raw)
To: TheNop, Linux/MIPS Development
Well, you dont need to configure kernel based on the chip revision. You
can determine the chip revision (on bootup) by reading the processor id
(PRID) and the CPU Mask register. Then, check the version number in the
driver and do the copy (for IP header alignment) if the version is 1.0
or 1.1
Thanks
Manish Lachwani
TheNop wrote:
> Manish Lachwani wrote:
>
>> Hello !
>>
>> Thanks for sending this. I have one question regarding the Yosemite
>> board that you have. What is the version of the Titan chip on the
>> board? Is it 1.0, 1.1 or 1.2?
>>
>> This is because 1.0 and 1.1 have a problem where the IP header is not
>> aligned on the Rx side. As a result, there was an extra copy involved
>> in the driver, i.e. titan_ge_slowpath. The latest version of the
>> driver only support Titan chip revision 1.2 in which this problem is
>> fixed
>>
>> Thanks
>> Manish Lachwani
>>
>>
>>
> I use the chip version 1.1.
> Now I have the problem, that I can not use the newest code, until 1.2
> version of the chip is available.
> Is it possible to make the code usable for all chip version by choosing
> the version at the kernel configuration?
>
> Best regards
> TheNop
>
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
2004-11-18 22:17 ` TheNop
2004-11-18 22:23 ` Manish Lachwani
@ 2004-11-19 17:32 ` Manish Lachwani
1 sibling, 0 replies; 12+ messages in thread
From: Manish Lachwani @ 2004-11-19 17:32 UTC (permalink / raw)
To: TheNop; +Cc: linux-mips
Hello !
If you are interested in creating a patch for supporting Titan GE in
older Titan versions (1.0 and 1.1), then I have indicated the part of
the diffs below that you will need to apply to the current driver
>
> /*
> + * 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;
> }
>
Thanks
Manish Lachwani
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
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
1 sibling, 1 reply; 12+ messages in thread
From: Ralf Baechle @ 2004-11-20 9:54 UTC (permalink / raw)
To: TheNop; +Cc: linux-mips
On Thu, Nov 18, 2004 at 11:43:51PM +0100, TheNop wrote:
> I use the chip version 1.1.
> Now I have the problem, that I can not use the newest code, until 1.2
> version of the chip is available.
> Is it possible to make the code usable for all chip version by choosing
> the version at the kernel configuration?
Titan 1.2 is available since quite a while - the dust on my board is
proof ;-) Since Titan 1.0 and 1.0 were shipped in very low numbers to
early customers only and will never be available in volume production the
support for them was removed. As I recall there were at least these
problems with Titan 1.0 and 1.1 in Linux:
- Linux uses the prefetch prepare for store operation.
- Coherency mode 5 which is mandatory for good performance and any kind
of sanity on SMP is now being used.
- The problem with the third ethernet port which Manish just had
described.
You can dig through XCVS, WebCVS or the linux-cvs archive to find where
I broke backward compatibility.
Ralf
^ permalink raw reply [flat|nested] 12+ messages in thread
* Re: Titan ethernet driver broken
2004-11-20 9:54 ` Ralf Baechle
@ 2004-11-21 7:26 ` Manish Lachwani
0 siblings, 0 replies; 12+ messages in thread
From: Manish Lachwani @ 2004-11-21 7:26 UTC (permalink / raw)
To: Ralf Baechle; +Cc: TheNop, linux-mips
Ralf Baechle wrote:
> On Thu, Nov 18, 2004 at 11:43:51PM +0100, TheNop wrote:
>
>
>>I use the chip version 1.1.
>>Now I have the problem, that I can not use the newest code, until 1.2
>>version of the chip is available.
>>Is it possible to make the code usable for all chip version by choosing
>>the version at the kernel configuration?
>
>
> Titan 1.2 is available since quite a while - the dust on my board is
> proof ;-) Since Titan 1.0 and 1.0 were shipped in very low numbers to
> early customers only and will never be available in volume production the
> support for them was removed. As I recall there were at least these
> problems with Titan 1.0 and 1.1 in Linux:
>
> - Linux uses the prefetch prepare for store operation.
> - Coherency mode 5 which is mandatory for good performance and any kind
> of sanity on SMP is now being used.
> - The problem with the third ethernet port which Manish just had
> described.
>
> You can dig through XCVS, WebCVS or the linux-cvs archive to find where
> I broke backward compatibility.
>
> Ralf
>
Hello !
Ralf, thanks for the good description. Anyways, just to make it a little
more clear. Port #2 (third ethernet port) was not working on Titan 1.0
and 1.1. This is because there is no interrupt line on which interrupts
for port #2 could be routed. And Titan MACs cannot share interrupts.
One other problem with 1.0 and 1.1 was that for incoming packets, the IP
header is not aligned. As a result, an extra copy was implemented in the
driver to align this IP header. This problem exists on all ports (0 and 1).
With Titan 1.2, there is no need for the extra copy and port #2 can be
enabled since there is an interrupt line which it can use.
And of course, 1.0 and 1.1 did not support the five state MOESI
protocol. They supported MEI only.
Thanks
Manish Lachwani
^ permalink raw reply [flat|nested] 12+ messages in thread
end of thread, other threads:[~2004-11-21 7:26 UTC | newest]
Thread overview: 12+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
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
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
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox