Re: sis190

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



> Message du 17/06/05 00:36
> De : "Francois Romieu" <[email protected]>
> 
> Can you give a try at:
> http://www.fr.zoreil.com/people/francois/misc/20050616-2.6.12-rc-sis190-test.patch
> 
> Please issue a few packets, say 4 to 8, and check your log after an
> ethtool -i eth0. Then wait for the Rx process to get stuck and issue
> the same ethtool command. You can probably lower NUM_RX_DESC to 16 or
> 32 to minimize the output.
> 
> --
> Ueimor
> 
> 

I noticed that you remove NET_IP_ALIGN in sis190_alloc_rx_skb(), 
but not in sis190_try_rx_copy(); though the driver "worked" like
yesterday...


BTW, i had to put the printk about RxdescRing in sis190_interrupt(),
as i had Kernel Oops when in sis190_get_drvinfo().


# diff -puN sis190-20050616.c sis190.c
--- sis190-20050616.c   2005-06-17 11:56:46.000000000 +0200
+++ sis190.c    2005-06-17 12:12:20.000000000 +0200
@@ -76,8 +76,8 @@ static int multicast_filter_limit = 32;
 /* MAC address length */
 #define MAC_ADDR_LEN   6

-#define NUM_TX_DESC    64      /* Number of Tx descriptor registers */
-#define NUM_RX_DESC    64      /* Number of Rx descriptor registers */
+#define NUM_TX_DESC    16      /* Number of Tx descriptor registers */
+#define NUM_RX_DESC    16      /* Number of Rx descriptor registers */
 #define TX_RING_BYTES  (NUM_TX_DESC * sizeof(struct TxDesc))
 #define RX_RING_BYTES  (NUM_RX_DESC * sizeof(struct RxDesc))
 #define RX_BUF_SIZE    1536    /* Rx Buffer size */
@@ -621,6 +621,8 @@ static irqreturn_t sis190_interrupt(int
        void __iomem *ioaddr = tp->mmio_addr;
        int handled = 0;
        int boguscnt;
+       unsigned int i;
+       u32 *u;

        for (boguscnt = max_interrupt_work; boguscnt > 0; boguscnt--) {
                u32 status = SIS_R32(IntrStatus);
@@ -637,7 +639,8 @@ static irqreturn_t sis190_interrupt(int

                SIS_W32(IntrStatus, status);

-               printk(KERN_INFO "%s: status = %08x\n", dev->name, status);
+               if ( status != 0x20000000)
+                 printk(KERN_INFO "%s: status = %08x\n", dev->name, status);

                if ((status & LinkChange) && netif_running(dev)) {
                        printk(KERN_INFO "%s: link change\n", dev->name);
@@ -647,8 +650,29 @@ static irqreturn_t sis190_interrupt(int
                if ((status & (TxQ0Int | RxQInt)) == 0)
                        break;

-               if (status & (RxQInt))
-                       sis190_rx_interrupt(dev, tp, ioaddr);
+               if (status & (RxQInt)) {
+                 if ( tp->cur_rx > 29) {
+                   printk(KERN_INFO "%s: dirty_rx=%ld cur_rx=%ld\n",
+                          dev->name, tp->dirty_rx, tp->cur_rx);
+                   u = (void *) tp->RxDescRing;
+                   printk(KERN_INFO "   PSize    status   addr     size     PSize    status   addr     size\n");
+                   for (i = 0; i < (NUM_RX_DESC / 2); i++) {
+                     printk(KERN_INFO "%02d:%08x %08x %08x %08x %08x %08x %08x %08x\n",
+                            i, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7]);
+                     u += 8;
+                   }
+                   printk(KERN_INFO "%s: dirty_tx=%ld cur_tx=%ld\n",
+                          dev->name, tp->dirty_tx, tp->cur_tx);
+                   u = (void *) tp->TxDescRing;
+                   printk(KERN_INFO "   PSize    status   addr     size     PSize    status   addr     size\n");
+                   for (i = 0; i < (NUM_TX_DESC / 2); i++) {
+                     printk(KERN_INFO "%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",
+                            i, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7]);
+                     u += 8;
+                   }
+                 }
+                 sis190_rx_interrupt(dev, tp, ioaddr);
+               }

                if (status & (TxQ0Int)) {
                        spin_lock(&tp->lock);
@@ -1233,31 +1257,11 @@ static void sis190_get_drvinfo(struct ne
                               struct ethtool_drvinfo *info)
 {
        struct sis190_private *tp = netdev_priv(dev);
-       unsigned int i;
-       u32 *u;

        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
        strcpy(info->bus_info, pci_name(tp->pci_dev));

-       printk(KERN_INFO "%s: dirty_rx=%ld cur_rx=%ld\n",
-              dev->name, tp->dirty_rx, tp->cur_rx);
-       u = (void *) tp->RxDescRing;
-       printk(KERN_INFO "   PSize    status   addr     size     PSize    status   addr     size\n");
-       for (i = 0; i < (NUM_RX_DESC / 2); i++) {
-               printk(KERN_INFO "%02d:%08x %08x %08x %08x %08x %08x %08x %08x\n",
-                      i, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7]);
-               u += 8;
-       }
-       printk(KERN_INFO "%s: dirty_tx=%ld cur_tx=%ld\n",
-              dev->name, tp->dirty_tx, tp->cur_tx);
-       u = (void *) tp->TxDescRing;
-       printk(KERN_INFO "   PSize    status   addr     size     PSize    status   addr     size\n");
-       for (i = 0; i < (NUM_TX_DESC / 2); i++) {
-               printk(KERN_INFO "%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",
-                      i, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7]);
-               u += 8;
-       }
 }

 static struct ethtool_ops sis190_ethtool_ops = {
@@ -1311,6 +1315,7 @@ static int __devinit sis190_init_one(str
        dev->open = sis190_open;
        dev->hard_start_xmit = sis190_start_xmit;
        dev->get_stats = sis190_get_stats;
+       SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
        dev->stop = sis190_close;
        dev->tx_timeout = sis190_tx_timeout;
        dev->set_multicast_list = sis190_set_rx_mode;
 



# dmesg
[...]
sis190 Gigabit Ethernet driver 1.2 loaded
ACPI: PCI Interrupt 0000:00:04.0[A] -> Link [LNKD] -> GSI 11 (level, low) -> IRQ 11
PCI: Setting latency timer of device 0000:00:04.0 to 64
0000:00:04.0: sis190 at ffffc20000004c00 (IRQ: 11), 00:11:2f:e9:42:70
eth0: Enabling Auto-negotiation.
eth0: status = 22000000
eth0: mii 0x1f = 0000.
eth0: mii lpa = 4501.
eth0: Link on 1000 Mbps Full Duplex mode.
eth0: no IPv6 routers present
eth0: status = 0000000c
eth0: status = 00000040
eth0: Rx status = 40040040
eth0: Rx PSize = 01010040
sk_buff[0]->tail = ffff810013381010
eth0: Rx status = c0000000
[...]
eth0: status = 20000040
eth0: dirty_rx=30 cur_rx=30
   PSize    status   addr     size     PSize    status   addr     size
00:00000000 c0000000 13381010 00000600 00000000 c0000000 13847010 00000600
01:00000000 c0000000 1edcb810 00000600 00000000 c0000000 1b694810 00000600
02:00000000 c0000000 1b697010 00000600 00000000 c0000000 077c4810 00000600
03:00000000 c0000000 07e15010 00000600 00000000 c0000000 06e3e810 00000600
04:00000000 c0000000 1719e810 00000600 00000000 c0000000 1b69b810 00000600
05:00000000 c0000000 1b694010 00000600 00000000 c0000000 07741010 00000600
06:00000000 c0000000 065d8010 00000600 00000000 c0000000 07a84010 00000600
07:010100a6 76040040 13381810 00000600 00000000 c0000000 1f7c1010 00000600
eth0: dirty_tx=36 cur_tx=36
   PSize    status   addr     size     PSize    status   addr     size
00 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
01 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
02 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
03 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
04 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
05 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
06 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
07 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
eth0: Rx status = 76040040
eth0: Rx PSize = 010100a6
sk_buff[0]->tail = ffff810013381810
eth0: Rx status = c0000000
eth0: status = 0000000c
eth0: status = 000000c0
eth0: dirty_rx=31 cur_rx=31
   PSize    status   addr     size     PSize    status   addr     size
00:00000000 c0000000 13381010 00000600 00000000 c0000000 13847010 00000600
01:00000000 c0000000 1edcb810 00000600 00000000 c0000000 1b694810 00000600
02:00000000 c0000000 1b697010 00000600 00000000 c0000000 077c4810 00000600
03:00000000 c0000000 07e15010 00000600 00000000 c0000000 06e3e810 00000600
04:00000000 c0000000 1719e810 00000600 00000000 c0000000 1b69b810 00000600
05:00000000 c0000000 1b694010 00000600 00000000 c0000000 07741010 00000600
06:00000000 c0000000 065d8010 00000600 00000000 c0000000 07a84010 00000600
07:00000000 c0000000 13381810 00000600 010100a6 76040040 1f7c1010 00000600
eth0: dirty_tx=37 cur_tx=37
   PSize    status   addr     size     PSize    status   addr     size
00 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
01 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
02 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
03 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
04 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
05 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
06 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
07 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000
eth0: Rx status = 76040040
eth0: Rx PSize = 010100a6
sk_buff[0]->tail = ffff81001f7c1010
eth0: Rx status = c0000000
eth0: status = 0000000c
eth0: status = 0000000c
eth0: status = 0000000c
eth0: status = 2000000c
eth0: status = 2000000c
eth0: status = 2000000c
eth0: status = 2000000c
eth0: status = 2000000c
eth0: status = 2000000c
eth0: status = 2000000c
eth0: status = 2000000c
[...]



No more traces about RxDescRing after that, as
status & (RxQInt) was always 0 in sis190_interrupt().




# ifconfig
eth0      Link encap:Ethernet  HWaddr 00:11:2F:E9:42:70
          inet addr:10.169.21.20  Bcast:10.169.23.255  Mask:255.255.252.0
          inet6 addr: fe80::211:2fff:fee9:4270/64 Scope:Link
          UP BROADCAST RUNNING MULTICAST  MTU:1500  Metric:1
          RX packets:32 errors:0 dropped:0 overruns:0 frame:0
          TX packets:87 errors:0 dropped:0 overruns:0 carrier:0
          collisions:0 txqueuelen:1000
          RX bytes:4833 (4.7 KiB)  TX bytes:7364 (7.1 KiB)
          Interrupt:11 Base address:0xdead



After that, i made various tries (most of them stupids).


I noticed that whith the default packet size, ping could work 
as long as i wanted.


So i removed the test "if (pkt_size < rx_copybreak) {" in sis190_try_rx_copy().


The driver now works "correctly" (ping, ssh, scp) as long as i want,
but probably not in the way you want...


I don't understand how the Rx packets are managed when  pkt_size is
greater than rx_copybreak...


I also tried to force 10H, 10F, 100H, 100F autoneg off on the other card.
All modes were working, but obviously something was wrong :
- 10H  0,4Mo/s both directions
- 10F  1,2Mo/s  "     "
- 100H   5Mo/s  "     "
- 100F 1,2Mo/s and 0,3Mo/s 

For 100F, sis190 reported "100 Mbps Half Duplex" and the other card 100 Full.

Autoneg on gived 100 Full detected and 5Mo/s both directions...




# diff -puN sis190-20050616.c sis190.c
--- sis190-20050616.c   2005-06-17 11:56:46.000000000 +0200
+++ sis190.c    2005-06-17 12:59:08.000000000 +0200
@@ -450,7 +450,6 @@ static inline int sis190_try_rx_copy(str
 {
        int ret = -1;

-       if (pkt_size < rx_copybreak) {
                struct sk_buff *skb;

                skb = dev_alloc_skb(pkt_size + NET_IP_ALIGN);
@@ -463,7 +462,6 @@ static inline int sis190_try_rx_copy(str
                        sis190_give_to_asic(desc, rx_buf_sz);
                        ret = 0;
                }
-       }
        return ret;
 }

@@ -637,7 +635,8 @@ static irqreturn_t sis190_interrupt(int

                SIS_W32(IntrStatus, status);

-               printk(KERN_INFO "%s: status = %08x\n", dev->name, status);
+               if ( status != 0x20000000)
+                 printk(KERN_INFO "%s: status = %08x\n", dev->name, status);

                if ((status & LinkChange) && netif_running(dev)) {
                        printk(KERN_INFO "%s: link change\n", dev->name);
@@ -647,8 +646,8 @@ static irqreturn_t sis190_interrupt(int
                if ((status & (TxQ0Int | RxQInt)) == 0)
                        break;

-               if (status & (RxQInt))
-                       sis190_rx_interrupt(dev, tp, ioaddr);
+               if (status & (RxQInt))
+                       sis190_rx_interrupt(dev, tp, ioaddr);

                if (status & (TxQ0Int)) {
                        spin_lock(&tp->lock);
@@ -845,7 +844,7 @@ static void sis190_phy_task(void * data)
                val = mdio_read(ioaddr, MII_LPA);
                printk(KERN_INFO "%s: mii lpa = %04x.\n", dev->name, val);
                for (p = reg31; p->ctl; p++) {
-                       if (val & p->val)
+                 if ((val & p->val) == p->val)
                                break;
                }
                if (p->ctl)
@@ -1233,31 +1232,11 @@ static void sis190_get_drvinfo(struct ne
                               struct ethtool_drvinfo *info)
 {
        struct sis190_private *tp = netdev_priv(dev);
-       unsigned int i;
-       u32 *u;

        strcpy(info->driver, DRV_NAME);
        strcpy(info->version, DRV_VERSION);
        strcpy(info->bus_info, pci_name(tp->pci_dev));

-       printk(KERN_INFO "%s: dirty_rx=%ld cur_rx=%ld\n",
-              dev->name, tp->dirty_rx, tp->cur_rx);
-       u = (void *) tp->RxDescRing;
-       printk(KERN_INFO "   PSize    status   addr     size     PSize    status   addr     size\n");
-       for (i = 0; i < (NUM_RX_DESC / 2); i++) {
-               printk(KERN_INFO "%02d:%08x %08x %08x %08x %08x %08x %08x %08x\n",
-                      i, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7]);
-               u += 8;
-       }
-       printk(KERN_INFO "%s: dirty_tx=%ld cur_tx=%ld\n",
-              dev->name, tp->dirty_tx, tp->cur_tx);
-       u = (void *) tp->TxDescRing;
-       printk(KERN_INFO "   PSize    status   addr     size     PSize    status   addr     size\n");
-       for (i = 0; i < (NUM_TX_DESC / 2); i++) {
-               printk(KERN_INFO "%02d %08x %08x %08x %08x %08x %08x %08x %08x\n",
-                      i, u[0], u[1], u[2], u[3], u[4], u[5], u[6], u[7]);
-               u += 8;
-       }
 }

 static struct ethtool_ops sis190_ethtool_ops = {
@@ -1311,6 +1290,7 @@ static int __devinit sis190_init_one(str
        dev->open = sis190_open;
        dev->hard_start_xmit = sis190_start_xmit;
        dev->get_stats = sis190_get_stats;
+       SET_ETHTOOL_OPS(dev, &sis190_ethtool_ops);
        dev->stop = sis190_close;
        dev->tx_timeout = sis190_tx_timeout;
        dev->set_multicast_list = sis190_set_rx_mode;



Regards
Pascal

-
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Please read the FAQ at  http://www.tux.org/lkml/

[Index of Archives]     [Kernel Newbies]     [Netfilter]     [Bugtraq]     [Photo]     [Stuff]     [Gimp]     [Yosemite News]     [MIPS Linux]     [ARM Linux]     [Linux Security]     [Linux RAID]     [Video 4 Linux]     [Linux for the blind]     [Linux Resources]
  Powered by Linux