Titan ethernet driver broken
Subsystems (3)
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
Quoted 11 lines · TheNop
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 lablelinux_2_6_8_1for 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
Quoted 13 lines · Manish Lachwani
Quoted 11 lines · TheNop
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 lablelinux_2_6_8_1for the titan ethernet driver works around this problem.Best regards
TheNop
Quoted 9 lines
Hello !
Can you send the diff between the
titan_ge(both .c and .h files) driver version inlinux_2_6_8_1and 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
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".
---
Quoted 2 lines
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)
---
Quoted 2 lines
#define
MODULE_VERSION(_version)\
MODULE_INFO(version, _version "\0xxxxxxxxxxxxxxxxxxxxxxxx")
224a211,227
Quoted 8 lines
/* sysfs stuff */
structmodule_attribute{ struct attribute attr; struct kernel_param *param; };struct
module_kobject
Quoted 9 lines
{
/* 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
Quoted 3 lines
/* 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_ };
---
Quoted 14 lines
{
__stringify(var), type };static inline void
__deprecatedMOD_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
}
Quoted 7 lines
static inline void
__deprecatedMOD_DEC_USE_COUNT(struct module *module){ module_put(module); }#define
MOD_INC_USE_COUNTMOD_INC_USE_COUNT(THIS_MODULE)
#defineMOD_DEC_USE_COUNTMOD_DEC_USE_COUNT(THIS_MODULE)
569c574,576
< #define MODULE_PARM(var,type) static void __attribute__((__unused__)) *__parm_##var = &MODULE_PARM_;
---
Quoted 3 lines
#define
MODULE_PARM(var,type)
#defineMOD_INC_USE_COUNTdo { } while (0)
#defineMOD_DEC_USE_COUNTdo { } 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 *);
---
Quoted 5 lines
extern void
inter_module_register(const char *, struct module *, const void *); extern voidinter_module_unregister(const char *);
extern const void *inter_module_get(const char *);
extern const void *inter_module_get_request(const char *, const char *); extern voidinter_module_put(const char *);
50c50
< #include <linux/dma-mapping.h>
---
Quoted 1 line
#include <
linux/version.h>
52a53
Quoted 1 line
#include <
linux/config.h>
53a55,56
Quoted 2 lines
#include <
linux/ptrace.h>
#include <linux/fcntl.h>
61a65
Quoted 1 line
#include <
linux/pci.h>
97a102
Quoted 1 line
static int
titan_ge_set_mac_address(struct net_device *, void *);
105a111
Quoted 1 line
static int
titan_ge_init(int);
119a126
Quoted 1 line
#ifdef
TITAN_RX_NAPI
120a128
Quoted 1 line
#endif
124,125d131
< static struct platform_device *titan_ge_device[3]; <
132,133d137
< static char titan_string[] = "titan";
<
450a455
Quoted 1 line
#ifdef
TITAN_RX_NAPI
468,470d472
< if (port_num == 2)
< ack &= ~(0x30000);
<
476a479,481
Quoted 3 lines
#else titan_ge_free_tx_queue(titan_ge_eth); titan_ge_receive_queue(netdev, 0);
477a483
Quoted 1 line
#endif
612,613d617
< struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev;
< volatile titan_ge_rx_desc *rx_desc;
614a619
Quoted 1 line
volatile titan_ge_rx_desc *rx_desc;
621,622c626,627
< dma_map_single(device, skb->data, TITAN_GE_JUMBO_BUFSIZE - 2,
< DMA_FROM_DEVICE);
---
Quoted 2 lines
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);
---
Quoted 2 lines
pci_map_single(0, skb->data, TITAN_GE_STD_BUFSIZE - 2,
PCI_DMA_FROMDEVICE);723d727
< unsigned long reg_data_1;
737c741
<
---
Quoted 1 line
#ifdef
TITAN_RX_NAPI
739c743,745
<
---
Quoted 3 lines
#else TITAN_GE_WRITE(0x000c, 0x00000100); /* No WCIMODE */#endif
748a755
Quoted 1 line
#ifdef
TITAN_RX_NAPI
750a758
Quoted 1 line
#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
Quoted 2 lines
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);
---
Quoted 2 lines
pci_map_single(0, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE);
1133a1071,1083
Quoted 5 lines
#ifndef
TITAN_RX_NAPI
/*
* Coalescing for the Rx path
*/
static unsigned longtitan_ge_rx_coal(unsigned long delay, int port)
Quoted 8 lines
{ 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,
---
Quoted 1 line
pci_free_consistent(0, titan_ge_eth->tx_desc_area_size,
1278a1215,1225
Quoted 11 lines
#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
Quoted 1 line
#endif
1408a1357,1395
Quoted 33 lines
* Do the slowpath route. This route is kicked off
* when the IP header is misaligned. Grrr ..
*/
static int titan_ge_slowpath(structsk_buff*skb,
titan_ge_packet*packet, structnet_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);
Quoted 6 lines
#endif
return 0; }/*
1436a1424
Quoted 1 line
#ifdef
TITAN_RX_NAPI
1440c1428
<
---
Quoted 1 line
#endif
1458a1447
Quoted 1 line
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);
---
Quoted 2 lines
if (titan_ge_slowpath(skb, &packet, netdev) < 0) goto out_next;
1469a1452
Quoted 1 line
#ifdef
TITAN_RX_NAPI
1475a1459,1462
Quoted 4 lines
#else ack = titan_ge_rx_task(netdev, titan_ge_eth); TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);#endif
1476a1464,1466
Quoted 3 lines
out_next:#ifdef
TITAN_RX_NAPI
1482a1473
Quoted 1 line
#endif
1488a1480,1481
Quoted 2 lines
#ifdef
TITAN_RX_NAPI
1589a1583
Quoted 1 line
#endif
1600a1595
Quoted 1 line
MOD_DEC_USE_COUNT;
1646,1647c1641
< dma_free_coherent(&titan_ge_device[port_num]->dev,
< titan_ge_eth->tx_desc_area_size,
---
Quoted 1 line
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,
---
Quoted 1 line
pci_free_consistent(0, titan_ge_eth->rx_desc_area_size,
1754a1748,1749
Quoted 2 lines
return;
1760c1755
< static int titan_ge_set_mac_address(struct net_device *dev, void *addr)
---
Quoted 1 line
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);
---
Quoted 1 line
int i;
1767,1769c1759,1760
< spin_lock_irq(&tp->lock);
< titan_ge_update_mac_address(dev);
< spin_unlock_irq(&tp->lock);
---
Quoted 2 lines
for (i = 0; i < 6; i++) netdev->dev_addr[i] = ((unsigned char *) addr)[i + 2];
1770a1762
Quoted 1 line
titan_ge_update_mac_address(netdev);
1784a1777,1835
Quoted 53 lines
* Register the Titan GE with the kernel
*/
static int__inittitan_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__inittitan_ge_cleanup_module(void)
Quoted 6 lines
{ iounmap((void *)titan_ge_sram); iounmap((void *)titan_ge_base); }/*
1878c1929
< static int __init titan_ge_probe(struct device *device)
---
Quoted 1 line
static int
titan_ge_init(int port)
1882d1932
< int port = to_platform_device(device)->id;1901a1952
Quoted 1 line
#ifdef
TITAN_RX_NAPI
1905c1956
<
---
Quoted 1 line
#endif
1938a1990
Quoted 1 line
#ifdef
TITAN_RX_NAPI
1939a1992,1994
Quoted 3 lines
#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);
< }
<
103a104,106
Quoted 3 lines
/* Support for Rx side NAPI */
#defineTITAN_RX_NAPI
Hello !
Can you please send the diffs using "diff -u" ? It would make the reading easy
Thanks
Manish Lachwani
Quoted 9 lines · Manish Lachwani
Hello !
Can you please send the diffs using "diff -u" ? It would make the reading easy
Thanks
Manish Lachwani
For sure.
Best regards
TheNop
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".
---
Quoted 2 lines
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)
---
Quoted 2 lines
#define
MODULE_VERSION(_version)\
MODULE_INFO(version, _version "\0xxxxxxxxxxxxxxxxxxxxxxxx")
224a211,227
Quoted 8 lines
/* sysfs stuff */
structmodule_attribute{ struct attribute attr; struct kernel_param *param; };struct
module_kobject
Quoted 9 lines
{
/* 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
Quoted 3 lines
/* 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_ };
---
Quoted 14 lines
{
__stringify(var), type };static inline void
__deprecatedMOD_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
}
Quoted 7 lines
static inline void
__deprecatedMOD_DEC_USE_COUNT(struct module *module){ module_put(module); }#define
MOD_INC_USE_COUNTMOD_INC_USE_COUNT(THIS_MODULE)
#defineMOD_DEC_USE_COUNTMOD_DEC_USE_COUNT(THIS_MODULE)
569c574,576
< #define MODULE_PARM(var,type) static void __attribute__((__unused__)) *__parm_##var = &MODULE_PARM_;
---
Quoted 3 lines
#define
MODULE_PARM(var,type)
#defineMOD_INC_USE_COUNTdo { } while (0)
#defineMOD_DEC_USE_COUNTdo { } 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 *);
---
Quoted 5 lines
extern void
inter_module_register(const char *, struct module *, const void *); extern voidinter_module_unregister(const char *);
extern const void *inter_module_get(const char *);
extern const void *inter_module_get_request(const char *, const char *); extern voidinter_module_put(const char *);
50c50
< #include <linux/dma-mapping.h>
---
Quoted 1 line
#include <
linux/version.h>
52a53
Quoted 1 line
#include <
linux/config.h>
53a55,56
Quoted 2 lines
#include <
linux/ptrace.h>
#include <linux/fcntl.h>
61a65
Quoted 1 line
#include <
linux/pci.h>
97a102
Quoted 1 line
static int
titan_ge_set_mac_address(struct net_device *, void *);
105a111
Quoted 1 line
static int
titan_ge_init(int);
119a126
Quoted 1 line
#ifdef
TITAN_RX_NAPI
120a128
Quoted 1 line
#endif
124,125d131
< static struct platform_device *titan_ge_device[3]; <
132,133d137
< static char titan_string[] = "titan";
<
450a455
Quoted 1 line
#ifdef
TITAN_RX_NAPI
468,470d472
< if (port_num == 2)
< ack &= ~(0x30000);
<
476a479,481
Quoted 3 lines
#else titan_ge_free_tx_queue(titan_ge_eth); titan_ge_receive_queue(netdev, 0);
477a483
Quoted 1 line
#endif
612,613d617
< struct device *device = &titan_ge_device[titan_ge_port->port_num]->dev;
< volatile titan_ge_rx_desc *rx_desc;
614a619
Quoted 1 line
volatile titan_ge_rx_desc *rx_desc;
621,622c626,627
< dma_map_single(device, skb->data, TITAN_GE_JUMBO_BUFSIZE - 2,
< DMA_FROM_DEVICE);
---
Quoted 2 lines
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);
---
Quoted 2 lines
pci_map_single(0, skb->data, TITAN_GE_STD_BUFSIZE - 2,
PCI_DMA_FROMDEVICE);723d727
< unsigned long reg_data_1;
737c741
<
---
Quoted 1 line
#ifdef
TITAN_RX_NAPI
739c743,745
<
---
Quoted 3 lines
#else TITAN_GE_WRITE(0x000c, 0x00000100); /* No WCIMODE */#endif
748a755
Quoted 1 line
#ifdef
TITAN_RX_NAPI
750a758
Quoted 1 line
#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
Quoted 2 lines
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);
---
Quoted 2 lines
pci_map_single(0, skb->data, skb_headlen(skb), PCI_DMA_TODEVICE);
1133a1071,1083
Quoted 5 lines
#ifndef
TITAN_RX_NAPI
/*
* Coalescing for the Rx path
*/
static unsigned longtitan_ge_rx_coal(unsigned long delay, int port)
Quoted 8 lines
{ 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,
---
Quoted 1 line
pci_free_consistent(0, titan_ge_eth->tx_desc_area_size,
1278a1215,1225
Quoted 11 lines
#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
Quoted 1 line
#endif
1408a1357,1395
Quoted 33 lines
* Do the slowpath route. This route is kicked off
* when the IP header is misaligned. Grrr ..
*/
static int titan_ge_slowpath(structsk_buff*skb,
titan_ge_packet*packet, structnet_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);
Quoted 6 lines
#endif
return 0; }/*
1436a1424
Quoted 1 line
#ifdef
TITAN_RX_NAPI
1440c1428
<
---
Quoted 1 line
#endif
1458a1447
Quoted 1 line
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);
---
Quoted 2 lines
if (titan_ge_slowpath(skb, &packet, netdev) < 0) goto out_next;
1469a1452
Quoted 1 line
#ifdef
TITAN_RX_NAPI
1475a1459,1462
Quoted 4 lines
#else ack = titan_ge_rx_task(netdev, titan_ge_eth); TITAN_GE_WRITE((0x5048 + (port_num << 8)), ack);#endif
1476a1464,1466
Quoted 3 lines
out_next:#ifdef
TITAN_RX_NAPI
1482a1473
Quoted 1 line
#endif
1488a1480,1481
Quoted 2 lines
#ifdef
TITAN_RX_NAPI
1589a1583
Quoted 1 line
#endif
1600a1595
Quoted 1 line
MOD_DEC_USE_COUNT;
1646,1647c1641
< dma_free_coherent(&titan_ge_device[port_num]->dev,
< titan_ge_eth->tx_desc_area_size,
---
Quoted 1 line
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,
---
Quoted 1 line
pci_free_consistent(0, titan_ge_eth->rx_desc_area_size,
1754a1748,1749
Quoted 2 lines
return;
1760c1755
< static int titan_ge_set_mac_address(struct net_device *dev, void *addr)
---
Quoted 1 line
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);
---
Quoted 1 line
int i;
1767,1769c1759,1760
< spin_lock_irq(&tp->lock);
< titan_ge_update_mac_address(dev);
< spin_unlock_irq(&tp->lock);
---
Quoted 2 lines
for (i = 0; i < 6; i++) netdev->dev_addr[i] = ((unsigned char *) addr)[i + 2];
1770a1762
Quoted 1 line
titan_ge_update_mac_address(netdev);
1784a1777,1835
Quoted 53 lines
* Register the Titan GE with the kernel
*/
static int__inittitan_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__inittitan_ge_cleanup_module(void)
Quoted 6 lines
{ iounmap((void *)titan_ge_sram); iounmap((void *)titan_ge_base); }/*
1878c1929
< static int __init titan_ge_probe(struct device *device)
---
Quoted 1 line
static int
titan_ge_init(int port)
1882d1932
< int port = to_platform_device(device)->id;1901a1952
Quoted 1 line
#ifdef
TITAN_RX_NAPI
1905c1956
<
---
Quoted 1 line
#endif
1938a1990
Quoted 1 line
#ifdef
TITAN_RX_NAPI
1939a1992,1994
Quoted 3 lines
#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);
< }
<
103a104,106
Quoted 3 lines
/* Support for Rx side NAPI */
#defineTITAN_RX_NAPI
Quoted 11 lines · TheNop
Quoted 9 lines · Manish Lachwani
Hello !
Can you please send the diffs using "diff -u" ? It would make the reading easy
Thanks
Manish Lachwani
Quoted 5 lines
For sure.
Best regards
TheNop
Ups, something went wrong.
Next try.
CU
include/linux/module.h +53 -48
@@ -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 32struct 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 */
drivers/net/titan_ge.c +187 -248
716 lines not on this page · raw message
drivers/net/titan_ge.h +3 -0
@@ -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
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
Quoted 11 lines · Manish Lachwani
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 fixedThanks
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
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
Quoted 20 lines · TheNop
Quoted 11 lines · Manish Lachwani
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 fixedThanks
Manish LachwaniI 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
Quoted 5 lines · TheNop
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
Quoted 20 lines · Ralf Baechle
Quoted 3 lines · TheNop
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.
Quoted 5 lines
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
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
Quoted 92 lines
/*
+ * Do the slowpath route. This route is kicked off
+ * when the IP header is misaligned. Grrr ..
+ */drivers/net/titan_ge.c +49
-10+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 ;
drivers/net/titan_ge.c line 1478
Quoted 10 lines
drivers/net/titan_ge.c +1
-0titan_ge_free_tx_queue(titan_ge_eth); }else titan_ge_eth->tx_threshold++; +#endif }return received_packets; }
Thanks
Manish Lachwani