rename and renumber storm patches
[openwrt/openwrt.git] / target / linux / storm / patches / 006-gmac_napi_tx.patch
diff --git a/target/linux/storm/patches/006-gmac_napi_tx.patch b/target/linux/storm/patches/006-gmac_napi_tx.patch
new file mode 100644 (file)
index 0000000..5861a65
--- /dev/null
@@ -0,0 +1,2094 @@
+--- a/drivers/net/sl351x_gmac.c
++++ b/drivers/net/sl351x_gmac.c
+@@ -43,9 +43,13 @@
+ #include <linux/mtd/kvctl.h>
++#define GET_RPTR(x) ((x) & 0xFFFF)
++#define GET_WPTR(x) ((x) >> 16)
++
+ #define        MIDWAY
+ #define        SL_LEPUS
+-#define VITESSE_G5SWITCH      1
++// #define VITESSE_G5SWITCH   1
++#undef VITESSE_G5SWITCH
+ #ifndef CONFIG_SL351x_RXTOE
+ //#define CONFIG_SL351x_RXTOE 1
+@@ -126,7 +130,6 @@
+  *************************************************************/
+ static int    gmac_initialized = 0;
+ TOE_INFO_T toe_private_data;
+-static int            do_again = 0;
+ static int rx_poll_enabled;
+ spinlock_t gmac_fq_lock;
+ unsigned int FLAG_SWITCH;
+@@ -190,7 +193,7 @@
+ void mac_set_sw_tx_weight(struct net_device *dev, char *weight);
+ void mac_get_hw_tx_weight(struct net_device *dev, char *weight);
+ void mac_set_hw_tx_weight(struct net_device *dev, char *weight);
+-static inline void toe_gmac_fill_free_q(void);
++static inline void toe_gmac_fill_free_q(int count);
+ #ifdef VITESSE_G5SWITCH
+ extern int Get_Set_port_status(void);
+@@ -295,12 +298,14 @@
+       for(j = 0; i<CONFIG_MAC_NUM; j++)
+       {
+               i=j;
++#ifdef VITESSE_G5SWITCH
+               if(Giga_switch){                // if gswitch present, swap eth0/1
+                       if(j==0)
+                               i=1;
+                       else if(j==1)
+                               i=0;
+               }
++#endif
+               tp = (GMAC_INFO_T *)&toe_private_data.gmac[i];
+               tp->dev = NULL;
+@@ -459,7 +464,7 @@
+               toe->gmac[1].dma_base_addr = TOE_GMAC1_DMA_BASE;
+         toe->gmac[0].auto_nego_cfg = 1;
+         toe->gmac[1].auto_nego_cfg = 1;
+-#ifdef CONFIG_SL3516_ASIC
++#ifndef CONFIG_SL3516_ASIC
+         toe->gmac[0].speed_cfg = GMAC_SPEED_1000;
+         toe->gmac[1].speed_cfg = GMAC_SPEED_1000;
+ #else
+@@ -508,7 +513,7 @@
+               // Write GLOBAL_QUEUE_THRESHOLD_REG
+               threshold.bits32 = 0;
+               threshold.bits.swfq_empty = (TOE_SW_FREEQ_DESC_NUM > 256) ? 255 :
+-                                                      TOE_SW_FREEQ_DESC_NUM/2;
++                                                      TOE_SW_FREEQ_DESC_NUM/16;
+               threshold.bits.hwfq_empty = (TOE_HW_FREEQ_DESC_NUM > 256) ? 256/4 :
+                                                       TOE_HW_FREEQ_DESC_NUM/4;
+               threshold.bits.toe_class = (TOE_TOE_DESC_NUM > 256) ? 256/4 :
+@@ -613,18 +618,25 @@
+       rwptr_reg.bits.rptr = 0;
+       toe->fq_rx_rwptr.bits32 = rwptr_reg.bits32;
+       writel(rwptr_reg.bits32, TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
++      printk("SWFQ: %08X\n", readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG));
+       // SW Free Queue Descriptors
+       for (i=0; i<TOE_SW_FREEQ_DESC_NUM; i++)
+       {
++              void *data = NULL;
+               sw_desc_ptr->word0.bits.buffer_size = SW_RX_BUF_SIZE;
+-              sw_desc_ptr->word1.bits.sw_id = i;      // used to locate skb
++              sw_desc_ptr->word1.bits.sw_id = 0;      // used to locate skb
+               if ( (skb = dev_alloc_skb(SW_RX_BUF_SIZE))==NULL)  /* allocate socket buffer */
+               {
+                       printk("%s::skb buffer allocation fail !\n",__func__); while(1);
+               }
+-              REG32(skb->data) = (unsigned int)skb;
++
++              data = skb->data;
+               skb_reserve(skb, SKB_RESERVE_BYTES);
++
++              REG32(data + 0) = (unsigned int)skb;
++              REG32(data + 4) = (unsigned short)i;
++
+               // toe->rx_skb[i] = skb;
+               sw_desc_ptr->word2.buf_adr = (unsigned int)__pa(skb->data);
+ //            consistent_sync((unsigned int)desc_ptr, sizeof(GMAC_RXDESC_T), PCI_DMA_TODEVICE);
+@@ -851,14 +863,14 @@
+ *----------------------------------------------------------------------*/
+ static void toe_init_default_queue(void)
+ {
+-      TOE_INFO_T                              *toe;
++      TOE_INFO_T              *toe;
+       volatile NONTOE_QHDR_T  *qhdr;
+-      GMAC_RXDESC_T                   *desc_ptr;
+-      DMA_SKB_SIZE_T                  skb_size;
++      GMAC_RXDESC_T           *desc_ptr;
++      DMA_SKB_SIZE_T          skb_size;
+       toe = (TOE_INFO_T *)&toe_private_data;
+       desc_ptr = (GMAC_RXDESC_T *)DMA_MALLOC((TOE_DEFAULT_Q0_DESC_NUM * sizeof(GMAC_RXDESC_T)),
+-                                                                                      (dma_addr_t *)&toe->gmac[0].default_desc_base_dma);
++                                             (dma_addr_t *)&toe->gmac[0].default_desc_base_dma);
+       if (!desc_ptr)
+       {
+               printk("%s::DMA_MALLOC fail !\n",__func__);
+@@ -866,14 +878,17 @@
+       }
+       memset((void *)desc_ptr, 0, TOE_DEFAULT_Q0_DESC_NUM * sizeof(GMAC_RXDESC_T));
+       toe->gmac[0].default_desc_base = (unsigned int)desc_ptr;
++      printk("toe->gmac[0].default_desc_base_dma: %08X\n", toe->gmac[0].default_desc_base_dma);
++
+       toe->gmac[0].default_desc_num = TOE_DEFAULT_Q0_DESC_NUM;
+       qhdr = (volatile NONTOE_QHDR_T *)TOE_DEFAULT_Q0_HDR_BASE;
+       qhdr->word0.base_size = ((unsigned int)toe->gmac[0].default_desc_base_dma & NONTOE_QHDR0_BASE_MASK) | TOE_DEFAULT_Q0_DESC_POWER;
+       qhdr->word1.bits32 = 0;
+       toe->gmac[0].rx_rwptr.bits32 = 0;
+       toe->gmac[0].default_qhdr = (NONTOE_QHDR_T *)qhdr;
++
+       desc_ptr = (GMAC_RXDESC_T *)DMA_MALLOC((TOE_DEFAULT_Q1_DESC_NUM * sizeof(GMAC_RXDESC_T)),
+-                                                                                      (dma_addr_t *)&toe->gmac[1].default_desc_base_dma);
++                                             (dma_addr_t *)&toe->gmac[1].default_desc_base_dma);
+       if (!desc_ptr)
+       {
+               printk("%s::DMA_MALLOC fail !\n",__func__);
+@@ -1071,12 +1086,16 @@
+           data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG) & ~tp->intr0_selected;
+           writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_0_REG);
++
+           data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_1_REG) & ~tp->intr1_selected;
+           writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_1_REG);
++
+           data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_2_REG) & ~tp->intr2_selected;
+           writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_2_REG);
++
+           data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_3_REG) & ~tp->intr3_selected;
+           writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_3_REG);
++
+           data = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG) & ~tp->intr4_selected;
+           writel(data, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+       }
+@@ -1176,11 +1195,11 @@
+       GMAC_CONFIG2_T  config2_val;
+       GMAC_CONFIG0_T  config0,config0_mask;
+       GMAC_CONFIG1_T  config1;
+-      #ifdef CONFIG_SL351x_NAT
+       GMAC_CONFIG3_T  config3_val;
+-      #endif
+       GMAC_TX_WCR0_T  hw_weigh;
+       GMAC_TX_WCR1_T  sw_weigh;
++
++      uint32_t weight = 0;
+ //    GMAC_HASH_ENABLE_REG0_T hash_ctrl;
+ //
+ #if 0 /* mac address will be set in late_initcall */
+@@ -1202,24 +1221,23 @@
+       //      config1.bits32 = 0x002004;      //next version
+       /* set flow control threshold */
+       config1.bits32 = 0;
+-      config1.bits.set_threshold = 32 / 2;
+-      config1.bits.rel_threshold = 32 / 4 * 3;
++      config1.bits.set_threshold = (32 / 2);
++      config1.bits.rel_threshold = (32 / 4) * 3;
+       gmac_write_reg(tp->base_addr, GMAC_CONFIG1, config1.bits32, 0xffffffff);
+-      /* set flow control threshold */
++      /* TODO: set flow control threshold */
+       config2_val.bits32 = 0;
+-      config2_val.bits.set_threshold = TOE_SW_FREEQ_DESC_NUM/2;
+-      config2_val.bits.rel_threshold = TOE_SW_FREEQ_DESC_NUM*3/4;
++      config2_val.bits.set_threshold = TOE_SW_FREEQ_DESC_NUM/4;
++      config2_val.bits.rel_threshold = TOE_SW_FREEQ_DESC_NUM/2;
+       gmac_write_reg(tp->base_addr, GMAC_CONFIG2, config2_val.bits32,0xffffffff);
+-      #ifdef CONFIG_SL351x_NAT
+-      /* set HW free queue flow control threshold */
++      /* TODO: set HW free queue flow control threshold */
+       config3_val.bits32 = 0;
+       config3_val.bits.set_threshold = PAUSE_SET_HW_FREEQ;
+       config3_val.bits.rel_threshold = PAUSE_REL_HW_FREEQ;
+       gmac_write_reg(tp->base_addr, GMAC_CONFIG3, config3_val.bits32,0xffffffff);
+-      #endif
+-      /* set_mcast_filter mask*/
++
++      /* TODO: set_mcast_filter mask*/
+       //      gmac_write_reg(tp->base_addr,GMAC_MCAST_FIL0,0x0,0xffffffff);
+       //  gmac_write_reg(tp->base_addr,GMAC_MCAST_FIL1,0x0,0xffffffff);
+@@ -1249,7 +1267,7 @@
+       config0.bits.dis_rx = 1;  /* disable rx */
+       config0.bits.dis_tx = 1;  /* disable tx */
+       config0.bits.loop_back = 0; /* enable/disable GMAC loopback */
+-      config0.bits.rx_err_detect = 1;
++      config0.bits.rx_err_detect = 1; /* TODO: was 1, means disabled, 0 enabled ! */
+       config0.bits.rgmii_en = 0;
+       config0.bits.rgmm_edge = 1;
+       config0.bits.rxc_inv = 0;
+@@ -1342,6 +1360,9 @@
+       gmac_write_reg(tp->dma_base_addr, GMAC_AHB_WEIGHT_REG, ahb_weight.bits32, ahb_weight_mask.bits32);
+       #endif
++      weight = gmac_read_reg(tp->dma_base_addr, GMAC_AHB_WEIGHT_REG);
++      printk("====> %08X\n", weight);
++
+       #if defined(CONFIG_SL351x_NAT) || defined(CONFIG_SL351x_RXTOE)
+       gmac_write_reg(tp->dma_base_addr, GMAC_SPR0, IPPROTO_TCP, 0xffffffff);
+       #endif
+@@ -1552,7 +1573,7 @@
+               rwptr.bits32 = readl(swtxq->rwptr_reg);
+               if (rwptr.bits.rptr == swtxq->finished_idx)
+                       break;
+-      curr_desc = (volatile GMAC_TXDESC_T *)swtxq->desc_base + swtxq->finished_idx;
++              curr_desc = (volatile GMAC_TXDESC_T *)swtxq->desc_base + swtxq->finished_idx;
+ //            consistent_sync((void *)curr_desc, sizeof(GMAC_TXDESC_T), PCI_DMA_FROMDEVICE);
+               word0.bits32 = curr_desc->word0.bits32;
+               word1.bits32 = curr_desc->word1.bits32;
+@@ -1573,6 +1594,7 @@
+                               swtxq->finished_idx = RWPTR_ADVANCE_ONE(swtxq->finished_idx, swtxq->total_desc_num);
+                               curr_desc = (GMAC_TXDESC_T *)swtxq->desc_base + swtxq->finished_idx;
+                               word0.bits32 = curr_desc->word0.bits32;
++
+ #ifdef _DUMP_TX_TCP_CONTENT
+                               if (curr_desc->word0.bits.buffer_size < 16)
+                               {
+@@ -1592,12 +1614,12 @@
+                       word0.bits.status_tx_ok = 0;
+                       if (swtxq->tx_skb[swtxq->finished_idx])
+                       {
+-                              if (interrupt)
+-                                      dev_kfree_skb_irq(swtxq->tx_skb[swtxq->finished_idx]);
+-                              else
+-                                      dev_kfree_skb(swtxq->tx_skb[swtxq->finished_idx]);
++                              dev_kfree_skb(swtxq->tx_skb[swtxq->finished_idx]);
+                               swtxq->tx_skb[swtxq->finished_idx] = NULL;
++                      } else {
++                              BUG();
+                       }
++
+                       curr_desc->word0.bits32 = word0.bits32;
+                       swtxq->curr_finished_desc = (GMAC_TXDESC_T *)curr_desc;
+                       swtxq->total_finished++;
+@@ -1624,31 +1646,29 @@
+ *----------------------------------------------------------------------*/
+ static int gmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
+ {
+-      GMAC_INFO_T                     *tp= dev->priv;
+-//    static unsigned int     pcount = 0;
+-//    unsigned int                    tx_qid;
+-    DMA_RWPTR_T                               rwptr;
+-      volatile GMAC_TXDESC_T  *curr_desc;
+-      int                                     snd_pages = skb_shinfo(skb)->nr_frags + 1;  /* get number of descriptor */
+-      int                                     frag_id = 0;
+-      int                                     len, total_len = skb->len;
++      GMAC_INFO_T *tp= dev->priv;
++      DMA_RWPTR_T rwptr;
++      GMAC_TXDESC_T *curr_desc;
++      int snd_pages = skb_shinfo(skb)->nr_frags + 1;  /* get number of descriptor */
++      int frag_id = 0;
++      int len, total_len = skb->len;
+       struct net_device_stats *isPtr;
+-      unsigned int                    free_desc;
+-      GMAC_SWTXQ_T                    *swtxq;
++      unsigned int free_desc;
++      GMAC_SWTXQ_T *swtxq;
+       register unsigned long  word0, word1, word2, word3;
+       unsigned short                  wptr, rptr;
+ #ifdef        L2_jumbo_frame
+       int header_len = skb->len;
+       struct iphdr    *ip_hdr;
+-    struct tcphdr     *tcp_hdr;
+-    int             tcp_hdr_len;
+-    unsigned char     *ptr;
+-    int             data_len,a;
+-    unsigned int    val;
++      struct tcphdr   *tcp_hdr;
++      int             tcp_hdr_len;
++      unsigned char   *ptr;
++      int             data_len,a;
++      unsigned int    val;
+ #endif
+ #ifdef GMAC_LEN_1_2_ISSUE
+-      int                                             total_pages;
++      int total_pages;
+       total_pages = snd_pages;
+ #endif
+@@ -1664,13 +1684,6 @@
+     }
+ #endif
+-#if 0
+-      if (storlink_ctl.recvfile==2)
+-      {
+-          printk("snd_pages=%d skb->len=%d\n",snd_pages,skb->len);
+-      }
+-#endif
+-
+ #ifdef GMAC_USE_TXQ0
+       #define tx_qid  0
+ #endif
+@@ -1703,9 +1716,9 @@
+       toe_gmac_tx_complete(tp, tx_qid, dev, 0);
+       if (wptr >= swtxq->finished_idx)
+-              free_desc = swtxq->total_desc_num - wptr - 1 + swtxq->finished_idx;
++              free_desc = swtxq->total_desc_num - wptr + swtxq->finished_idx;
+       else
+-              free_desc = swtxq->finished_idx - wptr - 1;
++              free_desc = swtxq->finished_idx - wptr;
+       if (free_desc < snd_pages)
+       {
+ //            spin_unlock(&tp->tx_mutex);
+@@ -2063,9 +2076,10 @@
+ struct net_device_stats * gmac_get_stats(struct net_device *dev)
+ {
+     GMAC_INFO_T *tp = (GMAC_INFO_T *)dev->priv;
++#if 0 /* don't read stats from hardware, scary numbers. */
+     // unsigned int        flags;
+-    unsigned int        pkt_drop;
+-    unsigned int        pkt_error;
++    unsigned int        pkt_drop = 0;
++    unsigned int        pkt_error = 0;
+     if (netif_running(dev))
+     {
+@@ -2073,10 +2087,14 @@
+         // spin_lock_irqsave(&tp->lock,flags);
+         pkt_drop = gmac_read_reg(tp->base_addr,GMAC_IN_DISCARDS);
+         pkt_error = gmac_read_reg(tp->base_addr,GMAC_IN_ERRORS);
++      printk("**** stack: %lu, hw: %lu\n", tp->ifStatics.rx_dropped, pkt_drop);
++
+         tp->ifStatics.rx_dropped = tp->ifStatics.rx_dropped + pkt_drop;
+         tp->ifStatics.rx_errors = tp->ifStatics.rx_errors + pkt_error;
+         // spin_unlock_irqrestore(&tp->lock,flags);
+     }
++#endif
++
+     return &tp->ifStatics;
+ }
+@@ -2401,36 +2419,63 @@
+ * toe_gmac_fill_free_q
+ * allocate buffers for free queue.
+ *----------------------------------------------------------------------*/
+-static inline void toe_gmac_fill_free_q(void)
++static inline void toe_gmac_fill_free_q(int count)
+ {
+       struct sk_buff  *skb;
+       volatile DMA_RWPTR_T    fq_rwptr;
+       volatile GMAC_RXDESC_T  *fq_desc;
+-      unsigned long   flags;
++      unsigned long flags;
++      unsigned short index;
++      int filled = 0;
++      static int entered;
+       // unsigned short max_cnt=TOE_SW_FREEQ_DESC_NUM>>1;
++      BUG_ON(entered == 1);
++
++      entered = 1;
++
++
+       fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+       // spin_lock_irqsave(&gmac_fq_lock, flags);
+       //while ((max_cnt--) && (unsigned short)RWPTR_ADVANCE_ONE(fq_rwptr.bits.wptr,
+       //                              TOE_SW_FREEQ_DESC_NUM) != fq_rwptr.bits.rptr) {
+-      while ((unsigned short)RWPTR_ADVANCE_ONE(fq_rwptr.bits.wptr,
+-                                      TOE_SW_FREEQ_DESC_NUM) != fq_rwptr.bits.rptr) {
++      index = fq_rwptr.bits.wptr;
++#if 0
++      printk("wptr: %hu, rptr: %hu, refill idx: %hu\n",
++             GET_RPTR(fq_rwptr.bits32),
++             GET_WPTR(fq_rwptr.bits32),
++             index);
++#endif
++
++      index = RWPTR_ADVANCE_ONE(index, TOE_SW_FREEQ_DESC_NUM);
++      fq_desc = (GMAC_RXDESC_T*)toe_private_data.swfq_desc_base + index;
++      while (fq_desc->word2.buf_adr == 0) {
++              void *data = NULL;
++
+               if ((skb = dev_alloc_skb(SW_RX_BUF_SIZE)) == NULL) {
+                       printk("%s::skb allocation fail!\n", __func__);
+-                      //while(1);
+-                      break;
++                      goto out;
+               }
+-              REG32(skb->data) = (unsigned int)skb;
++              ++ filled;
++              data = skb->data;
+               skb_reserve(skb, SKB_RESERVE_BYTES);
+-              // fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+-              fq_rwptr.bits.wptr = RWPTR_ADVANCE_ONE(fq_rwptr.bits.wptr,
+-                      TOE_SW_FREEQ_DESC_NUM);
+-              fq_desc = (GMAC_RXDESC_T*)toe_private_data.swfq_desc_base+fq_rwptr.bits.wptr;
++
++              REG32(data + 0) = (unsigned int)skb;
++              REG32(data + 4) = (unsigned short)index;
++
++              // printk("refill skb: %p, idx: %hu\n", skb, index);
+               fq_desc->word2.buf_adr = (unsigned int)__pa(skb->data);
+-              SET_WPTR(TOE_GLOBAL_BASE+GLOBAL_SWFQ_RWPTR_REG, fq_rwptr.bits.wptr);
+-              toe_private_data.fq_rx_rwptr.bits32 = fq_rwptr.bits32;
++      writel(0x07960202, TOE_GMAC0_BASE+GMAC_CONFIG0);
++              SET_WPTR(TOE_GLOBAL_BASE+GLOBAL_SWFQ_RWPTR_REG, index);
++      writel(0x07960200, TOE_GMAC0_BASE+GMAC_CONFIG0);
++
++              index = RWPTR_ADVANCE_ONE(index, TOE_SW_FREEQ_DESC_NUM);
++              fq_desc = (GMAC_RXDESC_T*)toe_private_data.swfq_desc_base+index;
+       }
++out:
+       // spin_unlock_irqrestore(&gmac_fq_lock, flags);
++
++      entered = 0;
+ }
+ // EXPORT_SYMBOL(toe_gmac_fill_free_q);
+@@ -2442,14 +2487,14 @@
+       unsigned int            status3;
+       unsigned int            status4;
+-      printk("%s\n", message);
+-
+       status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_0_REG);
+       status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
+       status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_2_REG);
+       status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_3_REG);
+       status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
++      printk("%s\n", message);
++
+       printk("status: s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
+                  status0, status1, status2, status3, status4);
+@@ -2468,8 +2513,9 @@
+       status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_3_REG);
+       status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+-      printk("select: s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
+-                 status0, status1, status2, status3, status4);
++      if (status0 || status1 || status2 || status3 || status4)
++                      printk("select: s0:%08X, s1:%08X, s2:%08X, s3:%08X, s4:%08X\n",
++                                 status0, status1, status2, status3, status4);
+ }
+ /*----------------------------------------------------------------------
+ * toe_gmac_interrupt
+@@ -2485,75 +2531,44 @@
+       unsigned int            status3;
+       unsigned int            status4;
+-//    struct net_device_stats *isPtr = (struct net_device_stats *)&tp->ifStatics;
+       toe = (TOE_INFO_T *)&toe_private_data;
+-//    handle NAPI
+-#ifdef CONFIG_SL_NAPI
+-      /* XXX: check this, changed from 'storlink_ctl.pauseoff == 1' to if (1) */
+-if (1)
+-{
+-/* disable GMAC interrupt */
+-    //toe_gmac_disable_interrupt(tp->irq);
+-//    isPtr->interrupts++;
++      if (0 && rx_poll_enabled) {
++              gmac_registers("interrupt handler");
++      }
++
+       /* read Interrupt status */
+       status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_0_REG);
+       status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
+       status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_2_REG);
+       status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_3_REG);
+       status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
+-      // prompt warning if status bit ON but not enabled
++
+ #if 0
+-      if (status0 & ~tp->intr0_enabled)
+-              printk("Intr 0 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status0, tp->intr0_enabled);
+-      if (status1 & ~tp->intr1_enabled)
+-              printk("Intr 1 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status1, tp->intr1_enabled);
+-      if (status2 & ~tp->intr2_enabled)
+-              printk("Intr 2 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status2, tp->intr2_enabled);
+-      if (status3 & ~tp->intr3_enabled)
+-              printk("Intr 3 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status3, tp->intr3_enabled);
+-      if (status4 & ~tp->intr4_enabled)
+-              printk("Intr 4 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status4, tp->intr4_enabled);
++      /* handle freeq interrupt first */
++      if (status4 & SWFQ_EMPTY_INT_BIT)
++      {
++              toe_gmac_fill_free_q();
++              writel(status4 & SWFQ_EMPTY_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
++              tp->sw_fq_empty_cnt++;
++      }
+ #endif
++      if (status4 & GMAC0_MIB_INT_BIT)
++              writel(GMAC0_MIB_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
++
++      if (status4 & GMAC0_RX_OVERRUN_INT_BIT)
++              writel(GMAC0_RX_OVERRUN_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
++
+       if (status0)
+               writel(status0 & tp->intr0_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_0_REG);
+-      if (status1)
+-              writel(status1 & tp->intr1_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_1_REG);
+       if (status2)
+               writel(status2 & tp->intr2_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_2_REG);
+       if (status3)
+               writel(status3 & tp->intr3_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_3_REG);
+-      if (status4)
+-              writel(status4 & tp->intr4_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
+-
+-#if 0
+-      /* handle freeq interrupt first */
+-      if (status4 & tp->intr4_enabled) {
+-              if ((status4 & SWFQ_EMPTY_INT_BIT) && (tp->intr4_enabled & SWFQ_EMPTY_INT_BIT))
+-              {
+-                      // unsigned long data = REG32(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+-                      //gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_4_REG,
+-                      //      tp->intr4_enabled & ~SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
+-
+-                      if (toe->gmac[0].dev && netif_running(toe->gmac[0].dev))
+-                              toe_gmac_handle_default_rxq(toe->gmac[0].dev,&toe->gmac[0]);
+-                      if (toe->gmac[1].dev && netif_running(toe->gmac[1].dev))
+-                              toe_gmac_handle_default_rxq(toe->gmac[1].dev,&toe->gmac[1]);
+-                      printk("\nfreeq int\n");
+-                      toe_gmac_fill_free_q();
+-                      tp->sw_fq_empty_cnt++;
+-              }
+-      }
+-#endif
+       // Interrupt Status 1
+-      if (status1 & tp->intr1_enabled)
++      if ((status1 & 3) || (status4 & 1))
+       {
+               #define G1_INTR0_BITS   (GMAC1_HWTQ13_EOF_INT_BIT | GMAC1_HWTQ12_EOF_INT_BIT | GMAC1_HWTQ11_EOF_INT_BIT | GMAC1_HWTQ10_EOF_INT_BIT)
+               #define G0_INTR0_BITS   (GMAC0_HWTQ03_EOF_INT_BIT | GMAC0_HWTQ02_EOF_INT_BIT | GMAC0_HWTQ01_EOF_INT_BIT | GMAC0_HWTQ00_EOF_INT_BIT)
+@@ -2563,7 +2578,7 @@
+               // because they should pass packets to upper layer
+               if (tp->port_id == 0)
+               {
+-                      if (netif_running(dev) && (status1 & G0_INTR0_BITS) && (tp->intr1_enabled & G0_INTR0_BITS))
++                      if (((status1 & G0_INTR0_BITS) && (tp->intr1_enabled & G0_INTR0_BITS)) || (status4 & 1))
+                       {
+                               if (status1 & GMAC0_HWTQ03_EOF_INT_BIT)
+                                       tp->hwtxq[3].eof_cnt++;
+@@ -2574,50 +2589,51 @@
+                               if (status1 & GMAC0_HWTQ00_EOF_INT_BIT)
+                                       tp->hwtxq[0].eof_cnt++;
+                       }
+-                              if (netif_running(dev) && (status1 & DEFAULT_Q0_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q0_INT_BIT))
++                      if (status1 & DEFAULT_Q0_INT_BIT || status4 & 1)
++                      {
++                              if (likely(netif_rx_schedule_prep(dev)))
+                               {
+-                                      if (!rx_poll_enabled && likely(netif_rx_schedule_prep(dev)))
+-                              {
+-                                      unsigned int data32;
++                                      unsigned int data32;
++
++                                      BUG_ON(rx_poll_enabled == 1);
+-                                              if (rx_poll_enabled)
+-                                                              gmac_registers("check #1");
++                                      /* Masks GMAC-0 rx interrupt */
++                                      data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
++                                      data32 &= ~(DEFAULT_Q0_INT_BIT);
++                                      writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-                                              BUG_ON(rx_poll_enabled == 1);
++                                      /* Masks GMAC-0 queue empty interrupt */
++                                      data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
++                                      data32 &= ~DEFAULT_Q0_INT_BIT;
++                                      writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
++                                      __netif_rx_schedule(dev);
++                                      rx_poll_enabled = 1;
++                              } else {
+ #if 0
+-                                      /* Masks GMAC-0 rx interrupt */
+-                                              data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-                                              data32 &= ~(DEFAULT_Q0_INT_BIT);
+-                                              writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-
+-                                      /* Masks GMAC-0 queue empty interrupt */
+-                                              data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+-                                              data32 &= ~DEFAULT_Q0_INT_BIT;
+-                                              writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+-
+-                                              data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+-                                              data32 &= ~DEFAULT_Q0_INT_BIT;
+-                                              writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+-#endif
+-
+-                                      // class-Q & TOE-Q are implemented in future
+-                                      //data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-                                      //data32 &= ~DEFAULT_Q0_INT_BIT;
+-                                              //writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-                                              //printk("\%s: DEFAULT_Q0_INT_BIT===================>>>>>>>>>>>>\n",__func__);
+-                                              writel(0x0, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_ENABLE_1_REG);
+-                                              //tp->total_q_cnt_napi=0;
+-                                              //rx_time = jiffies;
+-                                              //rx_old_bytes = isPtr->rx_bytes;
+-                                              __netif_rx_schedule(dev);
+-                                              rx_poll_enabled = 1;
+-                              }
++                                      unsigned int data32;
++
++                                      if (rx_poll_enabled)
++                                              gmac_registers("->poll() running.");
++                                      /* Masks GMAC-0 rx interrupt */
++                                      data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
++                                      data32 &= ~(DEFAULT_Q0_INT_BIT);
++                                      writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
++
++                                      /* Masks GMAC-0 queue empty interrupt */
++                                      data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
++                                      data32 &= ~DEFAULT_Q0_INT_BIT;
++                                      writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
++#endif
++                              }
++                      } else {
++                              if (0)
++                                      gmac_registers("status1 & DEFAULT_Q0_INT_BIT || status4 & 1");
+                       }
+               }
+-              else if (tp->port_id == 1)
++              else if (tp->port_id == 1 && netif_running(dev))
+               {
+-                      if (netif_running(dev) && (status1 & G1_INTR0_BITS) && (tp->intr1_enabled & G1_INTR0_BITS))
++                      if ((status1 & G1_INTR0_BITS) && (tp->intr1_enabled & G1_INTR0_BITS))
+                       {
+                               if (status1 & GMAC1_HWTQ13_EOF_INT_BIT)
+                                       tp->hwtxq[3].eof_cnt++;
+@@ -2629,14 +2645,14 @@
+                                       tp->hwtxq[0].eof_cnt++;
+                       }
+-                      if (netif_running(dev) && (status1 & DEFAULT_Q1_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q1_INT_BIT))
++                      if ((status1 & DEFAULT_Q1_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q1_INT_BIT))
+                       {
+                               if (!rx_poll_enabled && likely(netif_rx_schedule_prep(dev)))
+-                      {
+-                              unsigned int data32;
++                              {
++                                      unsigned int data32;
+                                       if (rx_poll_enabled)
+-                                                      gmac_registers("check #2");
++                                              gmac_registers("check #2");
+                                       BUG_ON(rx_poll_enabled == 1);
+@@ -2646,7 +2662,7 @@
+                                       data32 &= ~(DEFAULT_Q1_INT_BIT);
+                                       writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-                              /* Masks GMAC-1 queue empty interrupt */
++                                      /* Masks GMAC-1 queue empty interrupt */
+                                       data32  = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+                                       data32 &= ~DEFAULT_Q1_INT_BIT;
+                                       writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+@@ -2656,24 +2672,21 @@
+                                       writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
+ #endif
+-                              // disable GMAC-0 rx interrupt
+-                              // class-Q & TOE-Q are implemented in future
+-                              //data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-                              //data32 &= ~DEFAULT_Q1_INT_BIT;
++                                      // disable GMAC-0 rx interrupt
++                                      // class-Q & TOE-Q are implemented in future
++                                      //data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
++                                      //data32 &= ~DEFAULT_Q1_INT_BIT;
+                                       //writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+                                       //printk("\%s: 1111111111--->DEFAULT_Q1_INT_BIT===================>>>>>>>>>>>>\n",__func__);
+                                       writel(0x0, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_ENABLE_1_REG);
+                                       //tp->total_q_cnt_napi=0;
+                                       //rx_time = jiffies;
+                                       //rx_old_bytes = isPtr->rx_bytes;
+-                              __netif_rx_schedule(dev);
+-                              rx_poll_enabled = 1;
+-                      }
++                                      __netif_rx_schedule(dev);
++                                      rx_poll_enabled = 1;
++                              }
+                       }
+               }
+-      } else {
+-
+-              gmac_registers("check #3");
+       }
+       // Interrupt Status 0
+@@ -2814,676 +2827,93 @@
+               }
+       }
+-      //toe_gmac_enable_interrupt(tp->irq);
+-#ifdef IxscriptMate_1518
+-      if (storlink_ctl.pauseoff == 1)
+-      {
+-              GMAC_CONFIG0_T config0;
+-              config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
+-              config0.bits.dis_rx = 0;
+-              writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
+-              config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
+-              config0.bits.dis_rx = 0;
+-              writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
+-      }
+-#endif
+-//     enable_irq(gmac_irq[dev_index]);
+-      //printk("gmac_interrupt complete!\n\n");
+-//    return IRQ_RETVAL(handled);
+       return  IRQ_RETVAL(1);
+ }
+-else
+-{
+-#endif        //endif NAPI
++/*----------------------------------------------------------------------
++* gmac_get_phy_vendor
++*----------------------------------------------------------------------*/
++static unsigned int gmac_get_phy_vendor(int phy_addr)
++{
++    unsigned int      reg_val;
++    reg_val=(mii_read(phy_addr,0x02) << 16) + mii_read(phy_addr,0x03);
++    return reg_val;
++}
+-      /* disable GMAC interrupt */
+-    toe_gmac_disable_interrupt(tp->irq);
++/*----------------------------------------------------------------------
++* gmac_set_phy_status
++*----------------------------------------------------------------------*/
++void gmac_set_phy_status(struct net_device *dev)
++{
++      GMAC_INFO_T *tp = dev->priv;
++      GMAC_STATUS_T   status;
++      unsigned int    reg_val, ability,wan_port_id;
++      unsigned int    i = 0;
+-//    isPtr->interrupts++;
+-      /* read Interrupt status */
+-      status0 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_0_REG);
+-      status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
+-      status2 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_2_REG);
+-      status3 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_3_REG);
+-      status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
+-      // prompt warning if status bit ON but not enabled
++#ifdef VITESSE_G5SWITCH
++      if((tp->port_id == GMAC_PORT1)&&(Giga_switch==1)){
+ #if 0
+-      if (status0 & ~tp->intr0_enabled)
+-              printk("Intr 0 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status0, tp->intr0_enabled);
+-      if (status1 & ~tp->intr1_enabled)
+-              printk("Intr 1 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status1, tp->intr1_enabled);
+-      if (status2 & ~tp->intr2_enabled)
+-              printk("Intr 2 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status2, tp->intr2_enabled);
+-      if (status3 & ~tp->intr3_enabled)
+-              printk("Intr 3 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status3, tp->intr3_enabled);
+-      if (status4 & ~tp->intr4_enabled)
+-              printk("Intr 4 Status error. status = 0x%X, enable = 0x%X\n",
+-                              status4, tp->intr4_enabled);
+-#endif
+-#define       INTERRUPT_SELECT                        1
+-      if (status0)
+-              writel(status0 & tp->intr0_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_0_REG);
+-      if (status1)
+-              writel(status1 & tp->intr1_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_1_REG);
+-      if (status2)
+-              writel(status2 & tp->intr2_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_2_REG);
+-      if (status3)
+-              writel(status3 & tp->intr3_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_3_REG);
+-      if (status4)
+-              writel(status4 & tp->intr4_enabled, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
+-
+-      /* handle freeq interrupt first */
+-      if (status4 & tp->intr4_enabled) {
+-              if ((status4 & SWFQ_EMPTY_INT_BIT) && (tp->intr4_enabled & SWFQ_EMPTY_INT_BIT))
+-              {
+-                      // unsigned long data = REG32(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+-                      //gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_4_REG,
+-                      //      tp->intr4_enabled & ~SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
+-
+-                      //gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG,
+-                      //      SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
+-                      if (toe->gmac[0].dev && netif_running(toe->gmac[0].dev))
+-                              toe_gmac_handle_default_rxq(toe->gmac[0].dev,&toe->gmac[0]);
+-                      if (toe->gmac[1].dev && netif_running(toe->gmac[1].dev))
+-                              toe_gmac_handle_default_rxq(toe->gmac[1].dev,&toe->gmac[1]);
+-                      printk("\nfreeq int\n");
+-                      toe_gmac_fill_free_q();
+-                      tp->sw_fq_empty_cnt++;
+-
+-                      gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG, status4,
+-                              SWFQ_EMPTY_INT_BIT);
+-              }
+-      }
+-
+-      // Interrupt Status 1
+-      if (status1 & tp->intr1_enabled)
+-      {
+-              #define G1_INTR0_BITS   (GMAC1_HWTQ13_EOF_INT_BIT | GMAC1_HWTQ12_EOF_INT_BIT | GMAC1_HWTQ11_EOF_INT_BIT | GMAC1_HWTQ10_EOF_INT_BIT)
+-              #define G0_INTR0_BITS   (GMAC0_HWTQ03_EOF_INT_BIT | GMAC0_HWTQ02_EOF_INT_BIT | GMAC0_HWTQ01_EOF_INT_BIT | GMAC0_HWTQ00_EOF_INT_BIT)
+-              // Handle GMAC 0/1 HW Tx queue 0-3 EOF events
+-              // Only count
+-              // TOE, Classification, and default queues interrupts are handled by ISR
+-              // because they should pass packets to upper layer
+-              if (tp->port_id == 0)
+-              {
+-#ifndef       INTERRUPT_SELECT
+-                      if (netif_running(dev) && (status1 & G0_INTR0_BITS) && (tp->intr1_enabled & G0_INTR0_BITS))
+-                      {
+-                              if (status1 & GMAC0_HWTQ03_EOF_INT_BIT)
+-                                      tp->hwtxq[3].eof_cnt++;
+-                              if (status1 & GMAC0_HWTQ02_EOF_INT_BIT)
+-                                      tp->hwtxq[2].eof_cnt++;
+-                              if (status1 & GMAC0_HWTQ01_EOF_INT_BIT)
+-                                      tp->hwtxq[1].eof_cnt++;
+-                              if (status1 & GMAC0_HWTQ00_EOF_INT_BIT)
+-                                      tp->hwtxq[0].eof_cnt++;
+-#endif        //INTERRUPT_SELECT
+-#ifndef       INTERRUPT_SELECT
+-                      }
+-#endif        //INTERRUPT_SELECT
+-                      if (netif_running(dev) && (status1 & DEFAULT_Q0_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q0_INT_BIT))
+-                      {
+-                              tp->default_q_intr_cnt++;
+-                              toe_gmac_handle_default_rxq(dev, tp);
++              rcv_mask = SPI_read(2,0,0x10);                  // Receive mask
++              rcv_mask |= 0x4F;
++              for(i=0;i<4;i++){
++                      reg_val = BIT(26)|(i<<21)|(10<<16);
++                      SPI_write(3,0,1,reg_val);
++                      msleep(10);
++                      reg_val = SPI_read(3,0,2);
++                      if(reg_val & 0x0c00){
++                              printk("Port%d:Giga mode\n",i);
++                              SPI_write(1,i,0x00,0x300701B1);
++                              SPI_write(1,i,0x00,0x10070181);
++                              switch_pre_link[i]=LINK_UP;
++                              switch_pre_speed[i]=GMAC_SPEED_1000;
+                       }
+-#ifdef CONFIG_SL351x_RXTOE
+-                      if (netif_running(dev) && (status1 & TOE_IQ_ALL_BITS) &&
+-                          (tp->intr1_enabled & TOE_IQ_ALL_BITS)) {
+-                              //printk("status %x, bits %x, slct %x\n", status1, TOE_IQ_ALL_BITS, tp->intr1_selected);
+-                              toe_gmac_handle_toeq(dev, tp, status1);
+-                              //toe_gmac_handle_toeq(dev, toe, tp, status1);
++                      else{
++                              reg_val = BIT(26)|(i<<21)|(5<<16);
++                              SPI_write(3,0,1,reg_val);
++                              msleep(10);
++                              ability = (reg_val = SPI_read(3,0,2)&0x5e0) >>5;
++                              if ((ability & 0x0C)) /* 100M full duplex */
++                              {
++                                      SPI_write(1,i,0x00,0x30050472);
++                                      SPI_write(1,i,0x00,0x10050442);
++                                      printk("Port%d:100M\n",i);
++                                      switch_pre_link[i]=LINK_UP;
++                              switch_pre_speed[i]=GMAC_SPEED_100;
++                              }
++                              else if((ability & 0x03)) /* 10M full duplex */
++                              {
++                                      SPI_write(1,i,0x00,0x30050473);
++                                      SPI_write(1,i,0x00,0x10050443);
++                                      printk("Port%d:10M\n",i);
++                                      switch_pre_link[i]=LINK_UP;
++                                      switch_pre_speed[i]=GMAC_SPEED_10;
++                              }
++                              else{
++                                      SPI_write(1,i,0x00,BIT(16));                    // disable RX
++                                      SPI_write(5,0,0x0E,BIT(i));                     // dicard packet
++                                      while((SPI_read(5,0,0x0C)&BIT(i))==0)           // wait to be empty
++                                              msleep(1);
++
++                                      SPI_write(1,i,0x00,0x20000030);                 // PORT_RST
++                                      switch_pre_link[i]=LINK_DOWN;
++                                      switch_pre_speed[i]=GMAC_SPEED_10;
++                                      rcv_mask &= ~BIT(i);
++                                      SPI_write(2,0,0x10,rcv_mask);                   // Disable Receive
++                              }
+                       }
+-#endif
+               }
+-              else if (tp->port_id == 1)
+-              {
+-#ifndef       INTERRUPT_SELECT
+-                      if (netif_running(dev) && (status1 & G1_INTR0_BITS) && (tp->intr1_enabled & G1_INTR0_BITS))
+-                      {
+-                              if (status1 & GMAC1_HWTQ13_EOF_INT_BIT)
+-                                      tp->hwtxq[3].eof_cnt++;
+-                              if (status1 & GMAC1_HWTQ12_EOF_INT_BIT)
+-                                      tp->hwtxq[2].eof_cnt++;
+-                              if (status1 & GMAC1_HWTQ11_EOF_INT_BIT)
+-                                      tp->hwtxq[1].eof_cnt++;
+-                              if (status1 & GMAC1_HWTQ10_EOF_INT_BIT)
+-                                      tp->hwtxq[0].eof_cnt++;
+-#endif        //INTERRUPT_SELECT
+-#ifndef       INTERRUPT_SELECT
+-                      }
+-#endif        //INTERRUPT_SELECT
+-                      if (netif_running(dev) && (status1 & DEFAULT_Q1_INT_BIT) && (tp->intr1_enabled & DEFAULT_Q1_INT_BIT))
+-                      {
+-                              tp->default_q_intr_cnt++;
+-                              toe_gmac_handle_default_rxq(dev, tp);
+-                      }
+-#ifdef CONFIG_SL351x_RXTOE
+-                      if (netif_running(dev) && (status1 & TOE_IQ_ALL_BITS) &&
+-                          (tp->intr1_enabled & TOE_IQ_ALL_BITS)) {
+-                              //printk("status %x, bits %x, slct %x\n", status1, TOE_IQ_ALL_BITS, tp->intr1_selected);
+-                              toe_gmac_handle_toeq(dev, tp, status1);
+-                              //toe_gmac_handle_toeq(dev, toe, tp, status1);
+-                      }
+ #endif
+-              }
++              gmac_get_switch_status(dev);
++              gmac_write_reg(tp->base_addr, GMAC_STATUS, 0x7d, 0x0000007f);
++//            SPI_write(2,0,0x10,rcv_mask);                   // Enable Receive
++              return ;
+       }
++#endif
++      reg_val = gmac_get_phy_vendor(tp->phy_addr);
++      printk("GMAC-%d Addr %d Vendor ID: 0x%08x\n", tp->port_id, tp->phy_addr, reg_val);
+-      // Interrupt Status 0
+-      if (status0 & tp->intr0_enabled)
+-      {
+-
+-              #define ERR_INTR_BITS   (GMAC0_TXDERR_INT_BIT | GMAC0_TXPERR_INT_BIT |  \
+-                                                               GMAC1_TXDERR_INT_BIT | GMAC1_TXPERR_INT_BIT |  \
+-                                                               GMAC0_RXDERR_INT_BIT | GMAC0_RXPERR_INT_BIT |  \
+-                                                               GMAC1_RXDERR_INT_BIT | GMAC1_RXPERR_INT_BIT)
+-#ifndef       INTERRUPT_SELECT
+-              if (status0 &  ERR_INTR_BITS)
+-              {
+-                      if ((status0 & GMAC0_TXDERR_INT_BIT) && (tp->intr0_enabled & GMAC0_TXDERR_INT_BIT))
+-                      {
+-                              tp->txDerr_cnt[0]++;
+-                              printk("GMAC0 TX AHB Bus Error!\n");
+-                      }
+-                      if ((status0 & GMAC0_TXPERR_INT_BIT) && (tp->intr0_enabled & GMAC0_TXPERR_INT_BIT))
+-                      {
+-                              tp->txPerr_cnt[0]++;
+-                              printk("GMAC0 Tx Descriptor Protocol Error!\n");
+-                      }
+-                      if ((status0 & GMAC1_TXDERR_INT_BIT) && (tp->intr0_enabled & GMAC1_TXDERR_INT_BIT))
+-                      {
+-                              tp->txDerr_cnt[1]++;
+-                              printk("GMAC1 Tx AHB Bus Error!\n");
+-                      }
+-                      if ((status0 & GMAC1_TXPERR_INT_BIT) && (tp->intr0_enabled & GMAC1_TXPERR_INT_BIT))
+-                      {
+-                              tp->txPerr_cnt[1]++;
+-                              printk("GMAC1 Tx Descriptor Protocol Error!\n");
+-                      }
+-
+-                      if ((status0 & GMAC0_RXDERR_INT_BIT) && (tp->intr0_enabled & GMAC0_RXDERR_INT_BIT))
+-                      {
+-                              tp->RxDerr_cnt[0]++;
+-                              printk("GMAC0 Rx AHB Bus Error!\n");
+-                      }
+-                      if ((status0 & GMAC0_RXPERR_INT_BIT) && (tp->intr0_enabled & GMAC0_RXPERR_INT_BIT))
+-                      {
+-                              tp->RxPerr_cnt[0]++;
+-                              printk("GMAC0 Rx Descriptor Protocol Error!\n");
+-                      }
+-                      if ((status0 & GMAC1_RXDERR_INT_BIT) && (tp->intr0_enabled & GMAC1_RXDERR_INT_BIT))
+-                      {
+-                              tp->RxDerr_cnt[1]++;
+-                              printk("GMAC1 Rx AHB Bus Error!\n");
+-                      }
+-                      if ((status0 & GMAC1_RXPERR_INT_BIT) && (tp->intr0_enabled & GMAC1_RXPERR_INT_BIT))
+-                      {
+-                              tp->RxPerr_cnt[1]++;
+-                              printk("GMAC1 Rx Descriptor Protocol Error!\n");
+-                      }
+-              }
+-#endif        //INTERRUPT_SELECT
+-#ifndef       GMAX_TX_INTR_DISABLED
+-              if (tp->port_id == 1 && netif_running(dev) &&
+-                      (((status0 & GMAC1_SWTQ10_FIN_INT_BIT) && (tp->intr0_enabled & GMAC1_SWTQ10_FIN_INT_BIT))
+-                      ||
+-                      ((status0 & GMAC1_SWTQ10_EOF_INT_BIT) && (tp->intr0_enabled & GMAC1_SWTQ10_EOF_INT_BIT))))
+-              {
+-                      toe_gmac_tx_complete(&toe_private_data.gmac[1], 0, dev, 1);
+-              }
+-
+-              if (tp->port_id == 0 && netif_running(dev) &&
+-                      (((status0 & GMAC0_SWTQ00_FIN_INT_BIT) && (tp->intr0_enabled & GMAC0_SWTQ00_FIN_INT_BIT))
+-                      ||
+-                      ((status0 & GMAC0_SWTQ00_EOF_INT_BIT) && (tp->intr0_enabled & GMAC0_SWTQ00_EOF_INT_BIT))))
+-              {
+-                      toe_gmac_tx_complete(&toe_private_data.gmac[0], 0, dev, 1);
+-              }
+-#endif
+-              // clear enabled status bits
+-      }
+-      // Interrupt Status 4
+-#ifndef       INTERRUPT_SELECT
+-      if (status4 & tp->intr4_enabled)
+-      {
+-              #define G1_INTR4_BITS           (0xff000000)
+-              #define G0_INTR4_BITS           (0x00ff0000)
+-
+-              if (tp->port_id == 0)
+-              {
+-                      if ((status4 & G0_INTR4_BITS) && (tp->intr4_enabled & G0_INTR4_BITS))
+-                      {
+-                              if (status4 & GMAC0_RESERVED_INT_BIT)
+-                                      printk("GMAC0_RESERVED_INT_BIT is ON\n");
+-                              if (status4 & GMAC0_MIB_INT_BIT)
+-                                      tp->mib_full_cnt++;
+-                              if (status4 & GMAC0_RX_PAUSE_ON_INT_BIT)
+-                                      tp->rx_pause_on_cnt++;
+-                              if (status4 & GMAC0_TX_PAUSE_ON_INT_BIT)
+-                                      tp->tx_pause_on_cnt++;
+-                              if (status4 & GMAC0_RX_PAUSE_OFF_INT_BIT)
+-                                      tp->rx_pause_off_cnt++;
+-                              if (status4 & GMAC0_TX_PAUSE_OFF_INT_BIT)
+-                                      tp->rx_pause_off_cnt++;
+-                              if (status4 & GMAC0_RX_OVERRUN_INT_BIT)
+-                                      tp->rx_overrun_cnt++;
+-                              if (status4 & GMAC0_STATUS_CHANGE_INT_BIT)
+-                                      tp->status_changed_cnt++;
+-                      }
+-              }
+-              else if (tp->port_id == 1)
+-              {
+-                      if ((status4 & G1_INTR4_BITS) && (tp->intr4_enabled & G1_INTR4_BITS))
+-                      {
+-                              if (status4 & GMAC1_RESERVED_INT_BIT)
+-                                      printk("GMAC1_RESERVED_INT_BIT is ON\n");
+-                              if (status4 & GMAC1_MIB_INT_BIT)
+-                                      tp->mib_full_cnt++;
+-                              if (status4 & GMAC1_RX_PAUSE_ON_INT_BIT)
+-                              {
+-                                      //printk("Gmac pause on\n");
+-                                      tp->rx_pause_on_cnt++;
+-                              }
+-                              if (status4 & GMAC1_TX_PAUSE_ON_INT_BIT)
+-                              {
+-                                      //printk("Gmac pause on\n");
+-                                      tp->tx_pause_on_cnt++;
+-                              }
+-                              if (status4 & GMAC1_RX_PAUSE_OFF_INT_BIT)
+-                              {
+-                                      //printk("Gmac pause off\n");
+-                                      tp->rx_pause_off_cnt++;
+-                              }
+-                              if (status4 & GMAC1_TX_PAUSE_OFF_INT_BIT)
+-                              {
+-                                      //printk("Gmac pause off\n");
+-                                      tp->rx_pause_off_cnt++;
+-                              }
+-                              if (status4 & GMAC1_RX_OVERRUN_INT_BIT)
+-                              {
+-                                      //printk("Gmac Rx Overrun \n");
+-                                      tp->rx_overrun_cnt++;
+-                              }
+-                              if (status4 & GMAC1_STATUS_CHANGE_INT_BIT)
+-                                      tp->status_changed_cnt++;
+-                      }
+-              }
+-#if 0
+-              if ((status4 & SWFQ_EMPTY_INT_BIT) && (tp->intr4_enabled & SWFQ_EMPTY_INT_BIT))
+-              {
+-                      // unsigned long data = REG32(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+-//                    mac_stop_rxdma(tp->sc);
+-                      gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_ENABLE_4_REG,
+-                              tp->intr4_enabled & ~SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
+-
+-                      gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG,
+-                              SWFQ_EMPTY_INT_BIT, SWFQ_EMPTY_INT_BIT);
+-                      toe_gmac_fill_free_q();
+-                      tp->sw_fq_empty_cnt++;
+-
+-                      gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG, status4,
+-                              SWFQ_EMPTY_INT_BIT);
+-//#if 0
+-/*                    if (netif_running(dev))
+-                              toe_gmac_handle_default_rxq(dev, tp);
+-                      printk("SWFQ_EMPTY_INT_BIT is ON!\n");  // should not be happened */
+-//#endif
+-              }
+-#endif
+-      }
+-#endif        //INTERRUPT_SELECT
+-      toe_gmac_enable_interrupt(tp->irq);
+-//enable gmac rx function when do RFC 2544
+-#ifdef IxscriptMate_1518
+-      if (storlink_ctl.pauseoff == 1)
+-      {
+-              GMAC_CONFIG0_T config0;
+-              config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
+-              config0.bits.dis_rx = 0;
+-              writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
+-              config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
+-              config0.bits.dis_rx = 0;
+-              writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
+-      }
+-#endif
+-      //printk("gmac_interrupt complete!\n\n");
+-//    return IRQ_RETVAL(handled);
+-      return  IRQ_RETVAL(1);
+-#ifdef CONFIG_SL_NAPI
+-}
+-#endif
+-}
+-
+-/*----------------------------------------------------------------------
+-*     toe_gmac_handle_default_rxq
+-*     (1) Get rx Buffer for default Rx queue
+-*     (2) notify or call upper-routine to handle it
+-*     (3) get a new buffer and insert it into SW free queue
+-*     (4) Note: The SW free queue Read-Write Pointer should be locked when accessing
+-*----------------------------------------------------------------------*/
+-//static inline void toe_gmac_handle_default_rxq(struct net_device *dev, GMAC_INFO_T *tp)
+-static void toe_gmac_handle_default_rxq(struct net_device *dev, GMAC_INFO_T *tp)
+-{
+-      TOE_INFO_T                      *toe;
+-    GMAC_RXDESC_T     *curr_desc;
+-      struct sk_buff          *skb;
+-    DMA_RWPTR_T                       rwptr;
+-      unsigned int            pkt_size;
+-      int                                     max_cnt;
+-      unsigned int        desc_count;
+-      unsigned int        good_frame, chksum_status, rx_status;
+-      struct net_device_stats *isPtr = (struct net_device_stats *)&tp->ifStatics;
+-
+-//when do ixia RFC 2544 test and packet size is select 1518 bytes,disable gmace rx function immediately after one interrupt come in.
+-#ifdef IxscriptMate_1518
+-      if (storlink_ctl.pauseoff == 1)
+-      {
+-              GMAC_CONFIG0_T config0;
+-              config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
+-              config0.bits.dis_rx = 1;
+-              writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
+-              config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
+-              config0.bits.dis_rx = 1;
+-              writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
+-      }
+-#endif
+-      rwptr.bits32 = readl(&tp->default_qhdr->word1);
+-#if 0
+-      if (rwptr.bits.rptr != tp->rx_rwptr.bits.rptr)
+-      {
+-              mac_stop_txdma((struct net_device *)tp->dev);
+-              printk("Default Queue HW RD ptr (0x%x) != SW RD Ptr (0x%x)\n",
+-                              rwptr.bits32, tp->rx_rwptr.bits.rptr);
+-              while(1);
+-      }
+-#endif
+-      toe = (TOE_INFO_T *)&toe_private_data;
+-      max_cnt = DEFAULT_RXQ_MAX_CNT;
+-      while ((--max_cnt) && rwptr.bits.rptr != rwptr.bits.wptr)
+-//    while (rwptr.bits.rptr != rwptr.bits.wptr)
+-      {
+-//if packet size is not 1518 for RFC 2544,enable gmac rx function.The other packet size have RX workaround.
+-#ifdef IxscriptMate_1518
+-      if (storlink_ctl.pauseoff == 1)
+-              {
+-                      if (pkt_size != 1514)
+-                      {
+-                                              GMAC_CONFIG0_T config0;
+-                                              config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
+-                                              config0.bits.dis_rx = 0;
+-                                              writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
+-                                              config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
+-                                              config0.bits.dis_rx = 0;
+-                                              writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
+-                      }
+-              }
+-#endif
+-      curr_desc = (GMAC_RXDESC_T *)tp->default_desc_base + rwptr.bits.rptr;
+-//            consistent_sync(curr_desc, sizeof(GMAC_RXDESC_T), PCI_DMA_FROMDEVICE);
+-              tp->default_q_cnt++;
+-      tp->rx_curr_desc = (unsigned int)curr_desc;
+-      rx_status = curr_desc->word0.bits.status;
+-      chksum_status = curr_desc->word0.bits.chksum_status;
+-      tp->rx_status_cnt[rx_status]++;
+-      tp->rx_chksum_cnt[chksum_status]++;
+-        pkt_size = curr_desc->word1.bits.byte_count;  /*total byte count in a frame*/
+-              desc_count = curr_desc->word0.bits.desc_count; /* get descriptor count per frame */
+-              good_frame=1;
+-              if ((curr_desc->word0.bits32 & (GMAC_RXDESC_0_T_derr | GMAC_RXDESC_0_T_perr))
+-                      || (pkt_size < 60)
+-                  || (chksum_status & 0x4)
+-                      || rx_status)
+-              {
+-                      good_frame = 0;
+-                      if (curr_desc->word0.bits32 & GMAC_RXDESC_0_T_derr)
+-                              printk("%s::derr (GMAC-%d)!!!\n", __func__, tp->port_id);
+-                      if (curr_desc->word0.bits32 & GMAC_RXDESC_0_T_perr)
+-                              printk("%s::perr (GMAC-%d)!!!\n", __func__, tp->port_id);
+-                      if (rx_status)
+-                      {
+-                              if (rx_status == 4 || rx_status == 7)
+-                                      isPtr->rx_crc_errors++;
+-//                            printk("%s::Status=%d (GMAC-%d)!!!\n", __func__, rx_status, tp->port_id);
+-                      }
+-#ifdef SL351x_GMAC_WORKAROUND
+-                      else if (pkt_size < 60)
+-                      {
+-                              if (tp->short_frames_cnt < GMAC_SHORT_FRAME_THRESHOLD)
+-                                      tp->short_frames_cnt++;
+-                              if (tp->short_frames_cnt >= GMAC_SHORT_FRAME_THRESHOLD)
+-                              {
+-                                      GMAC_CONFIG0_T config0;
+-                                      config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
+-                                      config0.bits.dis_rx = 1;
+-                                      writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
+-                                      config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
+-                                      config0.bits.dis_rx = 1;
+-                                      writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
+-                              }
+-                      }
+-#endif
+-//                    if (chksum_status)
+-//                            printk("%s::Checksum Status=%d (GMAC-%d)!!!\n", __func__, chksum_status, tp->port_id);
+-                      skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES));
+-                      dev_kfree_skb_irq(skb);
+-              }
+-              if (good_frame)
+-              {
+-                      if (curr_desc->word0.bits.drop)
+-                              printk("%s::Drop (GMAC-%d)!!!\n", __func__, tp->port_id);
+-//                    if (chksum_status)
+-//                            printk("%s::Checksum Status=%d (GMAC-%d)!!!\n", __func__, chksum_status, tp->port_id);
+-
+-              /* get frame information from the first descriptor of the frame */
+-#ifdef SL351x_GMAC_WORKAROUND
+-                      if (tp->short_frames_cnt >= GMAC_SHORT_FRAME_THRESHOLD)
+-                      {
+-                              GMAC_CONFIG0_T config0;
+-                              config0.bits32 = readl(TOE_GMAC0_BASE+GMAC_CONFIG0);
+-                              config0.bits.dis_rx = 0;
+-                              writel(config0.bits32, TOE_GMAC0_BASE+GMAC_CONFIG0);
+-                              config0.bits32 = readl(TOE_GMAC1_BASE+GMAC_CONFIG0);
+-                              config0.bits.dis_rx = 0;
+-                              writel(config0.bits32, TOE_GMAC1_BASE+GMAC_CONFIG0);
+-                      }
+-                      tp->short_frames_cnt = 0;
+-#endif
+-                      isPtr->rx_packets++;
+-                      skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr - SKB_RESERVE_BYTES)));
+-                      if (!skb)
+-                      {
+-                              printk("Fatal Error!!skb==NULL\n");
+-                              goto next_rx;
+-                      }
+-                      tp->curr_rx_skb = skb;
+-                      // consistent_sync((void *)__va(curr_desc->word2.buf_adr), pkt_size, PCI_DMA_FROMDEVICE);
+-
+-      //              curr_desc->word2.buf_adr = 0;
+-
+-                      skb_reserve (skb, RX_INSERT_BYTES);     /* 16 byte align the IP fields. */
+-                      skb_put(skb, pkt_size);
+-                      skb->dev = dev;
+-                      if (chksum_status == RX_CHKSUM_IP_UDP_TCP_OK)
+-                      {
+-                              skb->ip_summed = CHECKSUM_UNNECESSARY;
+-#ifdef CONFIG_SL351x_NAT
+-                              if (nat_cfg.enabled && curr_desc->word3.bits.l3_offset && curr_desc->word3.bits.l4_offset)
+-                              {
+-                                      struct iphdr    *ip_hdr;
+-                                      ip_hdr = (struct iphdr *)&(skb->data[curr_desc->word3.bits.l3_offset]);
+-                                      sl351x_nat_input(skb,
+-                                                                      tp->port_id,
+-                                                                      (void *)curr_desc->word3.bits.l3_offset,
+-                                                                      (void *)curr_desc->word3.bits.l4_offset);
+-                              }
+-#endif
+-                              skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
+-#if 0
+-#ifdef CONFIG_SL351x_RXTOE
+-                              if (storlink_ctl.rx_max_pktsize) {
+-                                      struct iphdr    *ip_hdr;
+-                                      struct tcphdr   *tcp_hdr;
+-                                      int ip_hdrlen;
+-
+-                                      ip_hdr = (struct iphdr*)&(skb->data[0]);
+-                                      if ((skb->protocol == __constant_htons(ETH_P_IP)) &&
+-                                         ((ip_hdr->protocol & 0x00ff) == IPPROTO_TCP)) {
+-                                              ip_hdrlen = ip_hdr->ihl << 2;
+-                                              tcp_hdr = (struct tcphdr*)&(skb->data[ip_hdrlen]);
+-                                              if (tcp_hdr->syn) {
+-                                                      struct toe_conn* connection = init_toeq(ip_hdr->version,
+-                                                                      ip_hdr, tcp_hdr, toe, &(skb->data[0]) - 14);
+-                                                      TCP_SKB_CB(skb)->connection = connection;
+-                                                      //      hash_dump_entry(TCP_SKB_CB(skb)->connection->hash_entry_index);
+-                                                      //              printk("%s::skb data %x, conn %x, mode %x\n",
+-                                                      //                      __func__, skb->data, connection, connection->mode);
+-                                              }
+-                                      }
+-                              }
+-#endif
+-#endif
+-                      }
+-                      else if (chksum_status == RX_CHKSUM_IP_OK_ONLY)
+-                      {
+-                              skb->ip_summed = CHECKSUM_UNNECESSARY;
+-#ifdef CONFIG_SL351x_NAT
+-                              if (nat_cfg.enabled && curr_desc->word3.bits.l3_offset && curr_desc->word3.bits.l4_offset)
+-                              {
+-                                      struct iphdr            *ip_hdr;
+-                                      //struct tcphdr         *tcp_hdr;
+-                                      ip_hdr = (struct iphdr *)&(skb->data[curr_desc->word3.bits.l3_offset]);
+-                                      //tcp_hdr = (struct tcphdr *)&(skb->data[curr_desc->word3.bits.l4_offset]);
+-                                      if (ip_hdr->protocol == IPPROTO_UDP)
+-                                      {
+-                                              sl351x_nat_input(skb,
+-                                                                              tp->port_id,
+-                                                                              (void *)curr_desc->word3.bits.l3_offset,
+-                                                                              (void *)curr_desc->word3.bits.l4_offset);
+-                                      }
+-                                      else if (ip_hdr->protocol == IPPROTO_GRE)
+-                                      {
+-                                              sl351x_nat_input(skb,
+-                                                                      tp->port_id,
+-                                                                      (void *)curr_desc->word3.bits.l3_offset,
+-                                                                      (void *)curr_desc->word3.bits.l4_offset);
+-                                      }
+-                              }
+-#endif
+-                              skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
+-                      }
+-                      else
+-                      {
+-                              skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
+-                      }
+-
+-                      netif_rx(skb);  /* socket rx */
+-                      dev->last_rx = jiffies;
+-
+-                      isPtr->rx_bytes += pkt_size;
+-
+-        }
+-
+-next_rx:
+-              // advance one for Rx default Q 0/1
+-              rwptr.bits.rptr = RWPTR_ADVANCE_ONE(rwptr.bits.rptr, tp->default_desc_num);
+-              SET_RPTR(&tp->default_qhdr->word1, rwptr.bits.rptr);
+-      tp->rx_rwptr.bits32 = rwptr.bits32;
+-
+-      }
+-
+-      /* Handles first available packets only then refill the queue. */
+-      toe_gmac_fill_free_q();
+-}
+-
+-/*----------------------------------------------------------------------
+-* gmac_get_phy_vendor
+-*----------------------------------------------------------------------*/
+-static unsigned int gmac_get_phy_vendor(int phy_addr)
+-{
+-    unsigned int      reg_val;
+-    reg_val=(mii_read(phy_addr,0x02) << 16) + mii_read(phy_addr,0x03);
+-    return reg_val;
+-}
+-
+-/*----------------------------------------------------------------------
+-* gmac_set_phy_status
+-*----------------------------------------------------------------------*/
+-void gmac_set_phy_status(struct net_device *dev)
+-{
+-      GMAC_INFO_T *tp = dev->priv;
+-      GMAC_STATUS_T   status;
+-      unsigned int    reg_val, ability,wan_port_id;
+-      unsigned int    i = 0;
+-
+-#ifdef VITESSE_G5SWITCH
+-      if((tp->port_id == GMAC_PORT1)&&(Giga_switch==1)){
+-#if 0
+-              rcv_mask = SPI_read(2,0,0x10);                  // Receive mask
+-              rcv_mask |= 0x4F;
+-              for(i=0;i<4;i++){
+-                      reg_val = BIT(26)|(i<<21)|(10<<16);
+-                      SPI_write(3,0,1,reg_val);
+-                      msleep(10);
+-                      reg_val = SPI_read(3,0,2);
+-                      if(reg_val & 0x0c00){
+-                              printk("Port%d:Giga mode\n",i);
+-                              SPI_write(1,i,0x00,0x300701B1);
+-                              SPI_write(1,i,0x00,0x10070181);
+-                              switch_pre_link[i]=LINK_UP;
+-                              switch_pre_speed[i]=GMAC_SPEED_1000;
+-                      }
+-                      else{
+-                              reg_val = BIT(26)|(i<<21)|(5<<16);
+-                              SPI_write(3,0,1,reg_val);
+-                              msleep(10);
+-                              ability = (reg_val = SPI_read(3,0,2)&0x5e0) >>5;
+-                              if ((ability & 0x0C)) /* 100M full duplex */
+-                              {
+-                                      SPI_write(1,i,0x00,0x30050472);
+-                                      SPI_write(1,i,0x00,0x10050442);
+-                                      printk("Port%d:100M\n",i);
+-                                      switch_pre_link[i]=LINK_UP;
+-                              switch_pre_speed[i]=GMAC_SPEED_100;
+-                              }
+-                              else if((ability & 0x03)) /* 10M full duplex */
+-                              {
+-                                      SPI_write(1,i,0x00,0x30050473);
+-                                      SPI_write(1,i,0x00,0x10050443);
+-                                      printk("Port%d:10M\n",i);
+-                                      switch_pre_link[i]=LINK_UP;
+-                                      switch_pre_speed[i]=GMAC_SPEED_10;
+-                              }
+-                              else{
+-                                      SPI_write(1,i,0x00,BIT(16));                    // disable RX
+-                                      SPI_write(5,0,0x0E,BIT(i));                     // dicard packet
+-                                      while((SPI_read(5,0,0x0C)&BIT(i))==0)           // wait to be empty
+-                                              msleep(1);
+-
+-                                      SPI_write(1,i,0x00,0x20000030);                 // PORT_RST
+-                                      switch_pre_link[i]=LINK_DOWN;
+-                                      switch_pre_speed[i]=GMAC_SPEED_10;
+-                                      rcv_mask &= ~BIT(i);
+-                                      SPI_write(2,0,0x10,rcv_mask);                   // Disable Receive
+-                              }
+-                      }
+-              }
+-#endif
+-              gmac_get_switch_status(dev);
+-              gmac_write_reg(tp->base_addr, GMAC_STATUS, 0x7d, 0x0000007f);
+-//            SPI_write(2,0,0x10,rcv_mask);                   // Enable Receive
+-              return ;
+-      }
+-#endif
+-
+-      reg_val = gmac_get_phy_vendor(tp->phy_addr);
+-      printk("GMAC-%d Addr %d Vendor ID: 0x%08x\n", tp->port_id, tp->phy_addr, reg_val);
+-
+-      switch (tp->phy_mode)
++      switch (tp->phy_mode)
+       {
+               case GMAC_PHY_GMII:
+               mii_write(tp->phy_addr,0x04,0x05e1); /* advertisement 100M full duplex, pause capable on */
+@@ -3552,6 +2982,7 @@
+               status.bits.link = LINK_DOWN;
+               //              clear_bit(__LINK_STATE_START, &dev->state);
+               printk("Link Down (0x%04x) ", reg_val);
++#ifdef VITESSE_G5SWITCH
+               if(Giga_switch == 1)
+               {
+                               wan_port_id = 1;
+@@ -3565,6 +2996,7 @@
+                               storlink_ctl.link[ tp->port_id] = 0;
+ #endif
+               }
++#endif
+       }
+       else
+       {
+@@ -3572,6 +3004,7 @@
+               status.bits.link = LINK_UP;
+               //              set_bit(__LINK_STATE_START, &dev->state);
+               printk("Link Up (0x%04x) ",reg_val);
++#ifdef VITESSE_G5SWITCH
+               if(Giga_switch == 1)
+               {
+                               wan_port_id = 1;
+@@ -3585,6 +3018,7 @@
+                               storlink_ctl.link[ tp->port_id] = 1;
+ #endif
+               }
++#endif
+       }
+       //    value = mii_read(PHY_ADDR,0x05);
+@@ -3863,6 +3297,7 @@
+                       }
+               }
+               status.bits.link = LINK_UP; /* link up */
++#ifdef VITESSE_G5SWITCH
+               if(Giga_switch==1)
+               {
+                               wan_port_id = 1;
+@@ -3874,6 +3309,7 @@
+                               storlink_ctl.link[ tp->port_id] = 1;
+ #endif
+               }
++#endif
+               if ((ability & 0x20)==0x20)
+               {
+                       if (tp->flow_control_enable == 0)
+@@ -3914,6 +3350,7 @@
+       else
+       {
+               status.bits.link = LINK_DOWN; /* link down */
++#ifdef VITESSE_G5SWITCH
+               if(Giga_switch == 1)
+               {
+                               wan_port_id = 1;
+@@ -3925,6 +3362,7 @@
+                               storlink_ctl.link[ tp->port_id] = 0;
+ #endif
+               }
++#endif
+               if (tp->pre_phy_status == LINK_UP)
+               {
+                       printk("GMAC-%d LINK_Down......\n",tp->port_id);
+@@ -4298,86 +3736,102 @@
+ }
+ #ifdef CONFIG_SL_NAPI
++
++static int gmax_rx(struct net_device *dev, int *budget)
++{
++      return 0;
++}
++
++static int gmac_tx(struct net_device *dev, int *budget)
++{
++      return 0;
++}
++
+ /*----------------------------------------------------------------------
+ * gmac_rx_poll
+ *----------------------------------------------------------------------*/
+ static int gmac_rx_poll(struct net_device *dev, int *budget)
+ {
+-      TOE_INFO_T                      *toe;
+-    GMAC_RXDESC_T     *curr_desc;
+-      struct sk_buff          *skb;
+-    DMA_RWPTR_T                       rwptr;
+-    unsigned int data32;
+-      unsigned int            pkt_size;
+-      unsigned int        desc_count;
+-      unsigned int        good_frame, chksum_status, rx_status;
+-      int                 rx_pkts_num = 0;
+-      int                 quota = min(dev->quota, *budget);
+-      GMAC_INFO_T                     *tp = (GMAC_INFO_T *)dev->priv;
+-      unsigned int            status4;
+-      volatile DMA_RWPTR_T    fq_rwptr;
+-      // int                                  max_cnt = TOE_SW_FREEQ_DESC_NUM;//TOE_SW_FREEQ_DESC_NUM = 64
+-      //unsigned long         rx_old_bytes;
++      TOE_INFO_T      *toe;
++      GMAC_RXDESC_T   *curr_desc;
++      struct sk_buff  *skb;
++      DMA_RWPTR_T     rwptr;
++      unsigned int    data32;
++      unsigned int    pkt_size;
++      unsigned int    desc_count;
++      unsigned int    good_frame, chksum_status, rx_status;
++      int             rx_pkts_num = 0;
++      int             quota = min(dev->quota, *budget);
++      GMAC_INFO_T     *tp = (GMAC_INFO_T *)dev->priv;
++      unsigned int    status1;
++      unsigned int    status4;
+       struct net_device_stats *isPtr = (struct net_device_stats *)&tp->ifStatics;
+-      //unsigned long long    rx_time;
+-
+       BUG_ON(rx_poll_enabled == 0);
+-#if 1
+-      if (do_again)
+-      {
+-                      toe_gmac_fill_free_q();
+-                      status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
+-                      fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+-                      //printk("\n%s:: do_again toe_gmac_fill_free_q =======>status4=0x%x =====fq_rwptr =0x%8x======>JKJKJKJKJKJKJKJKJ \n", __func__,status4,fq_rwptr.bits32);
+-                      if (fq_rwptr.bits.wptr != fq_rwptr.bits.rptr)
+-                      {
+-                                              //status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
+-                                              do_again =0;
+-                                              //netif_rx_complete(dev);
+-                                              gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG, status4, 0x1);
+-                                              fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+-                                              rwptr.bits32 = readl(&tp->default_qhdr->word1);
+-                      }
+-                      else
+-                              return 1;
+-      }
+-#endif
+-      rwptr.bits32 = readl(&tp->default_qhdr->word1);
+-#if 0
+-      if (rwptr.bits.rptr != tp->rx_rwptr.bits.rptr)
+-      {
+-              mac_stop_txdma((struct net_device *)tp->dev);
+-              printk("Default Queue HW RD ptr (0x%x) != SW RD Ptr (0x%x)\n",
+-                              rwptr.bits32, tp->rx_rwptr.bits.rptr);
+-              while(1);
+-      }
+-#endif
++
+       toe = (TOE_INFO_T *)&toe_private_data;
+-      fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+-      //printk("%s:---Before-------------->Default Queue HW RW ptr (0x%8x),   fq_rwptr =0x%8x \n",__func__,rwptr.bits32,fq_rwptr.bits32 );
+-      //printk("%s:---Before while   rx_pkts_num=%d------rx_finished_idx=0x%x------->Default_Q [rwptr.bits.rptr(SW)=0x%x,   rwptr.bits.wptr(HW) = 0x%x ]---->Free_Q(SW_HW) = 0x%8x \n",__func__,rx_pkts_num,rx_finished_idx,rwptr.bits.rptr,rwptr.bits.wptr,fq_rwptr.bits32 );
+-//    while ((--max_cnt) && (rwptr.bits.rptr != rwptr.bits.wptr) && (rx_pkts_num < quota))
++rx_poll_retry:
++      status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
++      if (status1 & 1) {
++              writel(1, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
++      }
++      rwptr.bits32 = readl(&tp->default_qhdr->word1);
+       while ((rwptr.bits.rptr != rwptr.bits.wptr) && (rx_pkts_num < quota))
+       {
+-
+-      curr_desc = (GMAC_RXDESC_T *)tp->default_desc_base + rwptr.bits.rptr;
++              curr_desc = (GMAC_RXDESC_T *)tp->default_desc_base + rwptr.bits.rptr;
+               tp->default_q_cnt++;
+-      tp->rx_curr_desc = (unsigned int)curr_desc;
+-      rx_status = curr_desc->word0.bits.status;
+-      chksum_status = curr_desc->word0.bits.chksum_status;
+-      tp->rx_status_cnt[rx_status]++;
+-      tp->rx_chksum_cnt[chksum_status]++;
+-        pkt_size = curr_desc->word1.bits.byte_count;  /*total byte count in a frame*/
++              tp->rx_curr_desc = (unsigned int)curr_desc;
++              rx_status = curr_desc->word0.bits.status;
++              chksum_status = curr_desc->word0.bits.chksum_status;
++              tp->rx_status_cnt[rx_status]++;
++              tp->rx_chksum_cnt[chksum_status]++;
++              pkt_size = curr_desc->word1.bits.byte_count;  /*total byte count in a frame*/
+               desc_count = curr_desc->word0.bits.desc_count; /* get descriptor count per frame */
+               good_frame=1;
++
++              if (0) {
++
++                              int free, busy;
++                              uint32_t rwptr1;
++                              uint32_t rwptr2;
++
++                              rwptr1 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
++                              free = (GET_WPTR(rwptr1) - GET_RPTR(rwptr1)) & 0xFF;
++
++                              rwptr2 = readl(&tp->default_qhdr->word1);
++                              busy = (GET_RPTR(rwptr2) - GET_WPTR(rwptr2)) & 0xFF;
++
++                              if (GET_WPTR(rwptr1) == GET_RPTR(rwptr1)) {
++                                      printk("frame  status: %d\n"
++                                             "SWFQ: wptr: %hu, rptr: %hu, free: %d\n"
++                                             "GMAC: wptr: %hu, rptr: %hu, free: %d\n",
++                                             rx_status,
++                                             GET_WPTR(rwptr1), GET_RPTR(rwptr1), free,
++                                             GET_WPTR(rwptr2), GET_RPTR(rwptr2), busy);
++                              }
++              }
++
++              {
++                      GMAC_RXDESC_T   *fq_desc;
++                      void *data;
++                      struct sk_buff *skb;
++                      unsigned short idx;
++
++                      skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES));
++                      idx = (unsigned short)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES + 4));
++
++                      BUG_ON(idx > TOE_SW_FREEQ_DESC_NUM);
++                      BUG_ON(skb == NULL);
++                      fq_desc = (GMAC_RXDESC_T*)toe->swfq_desc_base + idx;
++                      fq_desc->word2.buf_adr = 0;
++              }
++
+               if ((curr_desc->word0.bits32 & (GMAC_RXDESC_0_T_derr | GMAC_RXDESC_0_T_perr))
+-                      || (pkt_size < 60)
++                  || (pkt_size < 60)
+                   || (chksum_status & 0x4)
+                   || rx_status )
+-//                    || rx_status || (rwptr.bits.rptr > rwptr.bits.wptr ))
+               {
+                       good_frame = 0;
+                       if (curr_desc->word0.bits32 & GMAC_RXDESC_0_T_derr)
+@@ -4388,7 +3842,6 @@
+                       {
+                               if (rx_status == 4 || rx_status == 7)
+                                       isPtr->rx_crc_errors++;
+-//                            printk("%s::Status=%d (GMAC-%d)!!!\n", __func__, rx_status, tp->port_id);
+                       }
+ #ifdef SL351x_GMAC_WORKAROUND
+                       else if (pkt_size < 60)
+@@ -4407,17 +3860,32 @@
+                               }
+                       }
+ #endif
+-//                    if (chksum_status)
+-//                            printk("%s::Checksum Status=%d (GMAC-%d)!!!\n", __func__, chksum_status, tp->port_id);
+                       skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES));
+-                      dev_kfree_skb_irq(skb);
++                      dev_kfree_skb(skb);
++
++                      if (0) {
++                              int free, busy;
++                              uint32_t rwptr1;
++                              uint32_t rwptr2;
++
++                              rwptr1 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
++                              free = (GET_WPTR(rwptr1) - GET_RPTR(rwptr1)) & 0xFF;
++
++                              rwptr2 = readl(&tp->default_qhdr->word1);
++                              busy = (GET_RPTR(rwptr2) - GET_WPTR(rwptr2)) & 0xFF;
++
++                              printk("frame  status: %d\n"
++                                     "SWFQ: wptr: %hu, rptr: %hu, free: %d\n"
++                                     "GMAC: wptr: %hu, rptr: %hu, free: %d\n",
++                                     rx_status,
++                                     GET_WPTR(rwptr1), GET_RPTR(rwptr1), free,
++                                     GET_WPTR(rwptr2), GET_RPTR(rwptr2), busy);
++                      }
+               }
+               if (good_frame)
+               {
+                       if (curr_desc->word0.bits.drop)
+                               printk("%s::Drop (GMAC-%d)!!!\n", __func__, tp->port_id);
+-//                    if (chksum_status)
+-//                            printk("%s::Checksum Status=%d (GMAC-%d)!!!\n", __func__, chksum_status, tp->port_id);
+ #ifdef SL351x_GMAC_WORKAROUND
+                       if (tp->short_frames_cnt >= GMAC_SHORT_FRAME_THRESHOLD)
+@@ -4432,225 +3900,118 @@
+                       }
+                       tp->short_frames_cnt = 0;
+ #endif
+-              /* get frame information from the first descriptor of the frame */
++                      /* get frame information from the first descriptor of the frame */
+                       isPtr->rx_packets++;
+-                      //consistent_sync((void *)__va(curr_desc->word2.buf_adr), pkt_size, PCI_DMA_FROMDEVICE);
++                      consistent_sync((void *)__va(curr_desc->word2.buf_adr), pkt_size, PCI_DMA_FROMDEVICE);
+                       skb = (struct sk_buff *)(REG32(__va(curr_desc->word2.buf_adr) - SKB_RESERVE_BYTES));
+                       tp->curr_rx_skb = skb;
+-      //              curr_desc->word2.buf_adr = 0;
+-                  //skb_reserve (skb, SKB_RESERVE_BYTES);
+                       skb_reserve (skb, RX_INSERT_BYTES);     /* 2 byte align the IP fields. */
+-                      //if ((skb->tail+pkt_size) > skb->end )
+-                      //printk("%s::------------->Here skb->len=%d,pkt_size= %d,skb->head=0x%x,skb->tail= 0x%x, skb->end= 0x%x\n", __func__, skb->len, pkt_size,skb->head,skb->tail,skb->end);
+                       skb_put(skb, pkt_size);
+-
+                       skb->dev = dev;
+                       if (chksum_status == RX_CHKSUM_IP_UDP_TCP_OK)
+                       {
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
+-#ifdef CONFIG_SL351x_NAT
+-                              if (nat_cfg.enabled && curr_desc->word3.bits.l3_offset && curr_desc->word3.bits.l4_offset)
+-                              {
+-                                      struct iphdr    *ip_hdr;
+-                                      ip_hdr = (struct iphdr *)&(skb->data[curr_desc->word3.bits.l3_offset]);
+-                                      sl351x_nat_input(skb,
+-                                                                      tp->port_id,
+-                                                                      (void *)curr_desc->word3.bits.l3_offset,
+-                                                                      (void *)curr_desc->word3.bits.l4_offset);
+-                              }
+-#endif
+                               skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
+-#if 0
+-#ifdef CONFIG_SL351x_RXTOE
+-                              if (storlink_ctl.rx_max_pktsize) {
+-                                      struct iphdr    *ip_hdr;
+-                                      struct tcphdr   *tcp_hdr;
+-                                      int ip_hdrlen;
+-
+-                                      ip_hdr = (struct iphdr*)&(skb->data[0]);
+-                                      if ((skb->protocol == __constant_htons(ETH_P_IP)) &&
+-                                         ((ip_hdr->protocol & 0x00ff) == IPPROTO_TCP)) {
+-                                              ip_hdrlen = ip_hdr->ihl << 2;
+-                                              tcp_hdr = (struct tcphdr*)&(skb->data[ip_hdrlen]);
+-                                              if (tcp_hdr->syn) {
+-                                                      struct toe_conn* connection = init_toeq(ip_hdr->version,
+-                                                                      ip_hdr, tcp_hdr, toe, &(skb->data[0]) - 14);
+-                                                      TCP_SKB_CB(skb)->connection = connection;
+-                                                      //      hash_dump_entry(TCP_SKB_CB(skb)->connection->hash_entry_index);
+-                                                      //              printk("%s::skb data %x, conn %x, mode %x\n",
+-                                                      //                      __func__, skb->data, connection, connection->mode);
+-                                              }
+-                                      }
+-                              }
+-#endif
+-#endif
+                       }
+                       else if (chksum_status == RX_CHKSUM_IP_OK_ONLY)
+                       {
+                               skb->ip_summed = CHECKSUM_UNNECESSARY;
+-#ifdef CONFIG_SL351x_NAT
+-                              if (nat_cfg.enabled && curr_desc->word3.bits.l3_offset && curr_desc->word3.bits.l4_offset)
+-                              {
+-                                      struct iphdr    *ip_hdr;
+-                                      ip_hdr = (struct iphdr *)&(skb->data[curr_desc->word3.bits.l3_offset]);
+-                                      if (ip_hdr->protocol == IPPROTO_UDP)
+-                                      {
+-                                              sl351x_nat_input(skb,
+-                                                                              tp->port_id,
+-                                                                              (void *)curr_desc->word3.bits.l3_offset,
+-                                                                              (void *)curr_desc->word3.bits.l4_offset);
+-                                      }
+-                                      else if (ip_hdr->protocol == IPPROTO_GRE)
+-                                      {
+-                                              sl351x_nat_input(skb,
+-                                                                      tp->port_id,
+-                                                                      (void *)curr_desc->word3.bits.l3_offset,
+-                                                                      (void *)curr_desc->word3.bits.l4_offset);
+-                                      }
+-                              }
+-#endif
+                               skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
+                       }
+                       else
+                       {
+                               skb->protocol = eth_type_trans(skb,dev); /* set skb protocol */
+                       }
+-                      //netif_rx(skb);  /* socket rx */
++
+                       netif_receive_skb(skb); //For NAPI
+                       dev->last_rx = jiffies;
+                       isPtr->rx_bytes += pkt_size;
+-                      //printk("------------------->isPtr->rx_bytes = %d\n",isPtr->rx_bytes);
+-
++              }
+-        }
+               // advance one for Rx default Q 0/1
+               rwptr.bits.rptr = RWPTR_ADVANCE_ONE(rwptr.bits.rptr, tp->default_desc_num);
+               SET_RPTR(&tp->default_qhdr->word1, rwptr.bits.rptr);
+-      tp->rx_rwptr.bits32 = rwptr.bits32;
++              tp->rx_rwptr.bits32 = rwptr.bits32;
+               rx_pkts_num++;
+-              //rwptr.bits32 = readl(&tp->default_qhdr->word1);//try read default_qhdr again
+-              //fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+-              //printk("%s:---Loop  -------->rx_pkts_num=%d------------>Default Queue HW RW ptr = (0x%8x),   fq_rwptr =0x%8x \n",__func__,rx_pkts_num,rwptr.bits32,fq_rwptr.bits32 );
+-#if 0
+-              if ((status4 & 0x1) == 0)
+-              {
+-                      //if (!((dev->last_rx <= (rx_time + 2)) &&  (isPtr->rx_bytes > (rx_old_bytes + 1000000 ))))
+-                      if (tp->total_q_cnt_napi < 1024)
+-                      {
+-                              tp->total_q_cnt_napi++;
+-                              toe_gmac_fill_free_q();  //for iperf test disable
+-                      }
+-                      //else
+-                              //printk("%s:---isPtr->rx_bytes =%u , rx_old_bytes =%u\n",__func__,isPtr->rx_bytes,rx_old_bytes );
++              // rwptr.bits32 = readl(&tp->default_qhdr->word1);
++              status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
++              if (status4 & 1) {
++                      writel(status4 & SWFQ_EMPTY_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
+               }
++
++              toe_gmac_fill_free_q(5);
++      }
++
++#if 0
++      /* avoid races with hard_start_xmit() */
++
++      spin_lock(&gmac_fq_lock);
++      toe_gmac_tx_complete(&toe_private_data.gmac[0], 0, dev, 1);
++      spin_unlock(&gmac_fq_lock);
+ #endif
+-              //rwptr.bits.rptr = RWPTR_ADVANCE_ONE(rwptr.bits.rptr, tp->default_desc_num);
+-              //printk("%s:---Loop  -------->rx_pkts_num=%d----rwptr.bits.rptr=0x%x-------->Default Queue HW RW ptr = (0x%8x),   fq_rwptr =0x%8x \n",__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits32,fq_rwptr.bits32 );
+-              //printk("%s:---Loop  rx_pkts_num=%d------rwptr.bits.rptr=0x%x------->Default_Q [rwptr.bits.rptr(SW)=0x%x,   rwptr.bits.wptr(HW) = 0x%x ]---->Free_Q(SW_HW) = 0x%8x \n",__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.rptr,rwptr.bits.wptr,fq_rwptr.bits32 );
++
++      status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
++      if (status4 & 1)
++      {
++              writel(status4 & SWFQ_EMPTY_INT_BIT, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_STATUS_4_REG);
++              status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);
++              toe_gmac_fill_free_q(rx_pkts_num);
+       }
+-      // advance one for Rx default Q 0/1
+-              //rwptr.bits.rptr = RWPTR_ADVANCE_ONE(rwptr.bits.rptr, tp->default_desc_num);
+-              //SET_RPTR(&tp->default_qhdr->word1, rwptr.bits.rptr);
+-      //tp->rx_rwptr.bits32 = rwptr.bits32;
+-      //rwptr.bits.rptr = rwptr.bits.rptr;
++      rwptr.bits32 = readl(&tp->default_qhdr->word1);
++      if (rwptr.bits.rptr != rwptr.bits.wptr &&
++          quota > rx_pkts_num)
++              goto rx_poll_retry;
+       dev->quota -= rx_pkts_num;
+       *budget -= rx_pkts_num;
+-      status4 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_4_REG);//try read SWFQ empty again
+-      //fq_rwptr.bits32 = readl(TOE_GLOBAL_BASE + GLOBAL_SWFQ_RWPTR_REG);
+-      rwptr.bits32 = readl(&tp->default_qhdr->word1); //try read default_qhdr again
+-      //printk("%s:---After    rx_pkts_num=%d------rwptr.bits.rptr=0x%x------->Default_Q [rwptr.bits.rptr(SW)=0x%x,   rwptr.bits.wptr(HW) = 0x%x ]---->Free_Q(SW_HW) = 0x%8x \n",__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.rptr,rwptr.bits.wptr,fq_rwptr.bits32 );
+-//    if (rwptr.bits.rptr > rwptr.bits.wptr )
+-//                    {
+-                              //toe_gmac_disable_rx(dev);
+-                              //wait_event_interruptible_timeout(freeq_wait,
+-                                      //(rx_pkts_num == 100), CMTP_INTEROP_TIMEOUT);
+-                              //printk("\n%s:: return 22222=======> rx_pkts_num =%d,   rwptr.bits.rptr=%d,   rwptr.bits.wptr = %d ====---------=======>JKJKJKJKJK\n",
+-                                      //__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.wptr);
+-//                            return 1;
+-//                    }
+-
+-      if (rwptr.bits.rptr == rwptr.bits.wptr)
++      /* Receive queue is empty now */
++      if (quota >= rx_pkts_num)
+       {
+-              // unsigned int data32;
+-                      //printk("%s:---[rwptr.bits.rptr == rwptr.bits.wptr]   rx_pkts_num=%d------rwptr.bits.rptr=0x%x------->Default_Q [rwptr.bits.rptr(SW)=0x%x,   rwptr.bits.wptr(HW) = 0x%x ]---->Free_Q(SW_HW) = 0x%8x \n",__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.rptr,rwptr.bits.wptr,fq_rwptr.bits32 );
+-
+-          /* Receive descriptor is empty now */
+-#if 1
+-     if (status4 & 0x1)
+-                      {
+-                              do_again =1;
+-                              //writel(0x40400000, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_ENABLE_4_REG); //disable SWFQ empty interrupt
+-                              //toe_gmac_disable_interrupt(tp->irq);
+-                              tp->sw_fq_empty_cnt++;
+-                              //toe_gmac_disable_rx(dev);
+-                              writel(0x07960202, TOE_GMAC0_BASE+GMAC_CONFIG0);
+-                              writel(0x07960202, TOE_GMAC1_BASE+GMAC_CONFIG0);
+-                              //printk("\n%s ::  freeq int-----tp->sw_fq_empty_cnt  =%d---------====================----------------->\n",__func__,tp->sw_fq_empty_cnt);
+-                              //while ((fq_rwptr.bits.wptr >= (fq_rwptr.bits.rptr+256)) || (fq_rwptr.bits.wptr <= (fq_rwptr.bits.rptr+256)))
+-                              //{
+-                                      //gmac_write_reg(TOE_GLOBAL_BASE, GLOBAL_INTERRUPT_STATUS_4_REG, status4,
+-                                      //0x1);
+-                              //printk("\n%s::fq_rwptr.wrptr = %x =======> ===========>here \n", __func__,fq_rwptr.bits32);
+-                              //if ((status4 & 0x1) == 0)
+-                                      //break;
+-                               return 1;
+-                              //}
++              unsigned long flags;
++              netif_rx_complete(dev);
++              rx_poll_enabled = 0;
++#if 0
++              status1 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_STATUS_1_REG);
++              if (status1 & 1) {
++                      if (netif_rx_reschedule(dev, rx_pkts_num)) {
++                              rx_poll_enabled = 1;
++                              return 1;
+                       }
++              }
+ #endif
+-        //toe_gmac_fill_free_q();
+-        netif_rx_complete(dev);
+-
+-              rx_poll_enabled = 0;
+-              data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-              if (tp->port_id == 0)
+-                              data32 |= DEFAULT_Q0_INT_BIT;
+-              else
+-                              data32 |= DEFAULT_Q1_INT_BIT;
+-              writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
++              spin_lock_irqsave(&gmac_fq_lock, flags);
+               data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+               if (tp->port_id == 0)
+-                              data32 |= DEFAULT_Q0_INT_BIT;
++                      data32 |= DEFAULT_Q0_INT_BIT;
+               else
+-                              data32 |= DEFAULT_Q1_INT_BIT;
++                      data32 |= DEFAULT_Q1_INT_BIT;
+               writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_4_REG);
+-              data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
++              data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+               if (tp->port_id == 0)
+-                              data32 |= DEFAULT_Q0_INT_BIT;
++                      data32 |= DEFAULT_Q0_INT_BIT;
+               else
+-                              data32 |= DEFAULT_Q1_INT_BIT;
+-              writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_SELECT_4_REG);
++                      data32 |= DEFAULT_Q1_INT_BIT;
++              writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-        // enable GMAC-0 rx interrupt
+-        // class-Q & TOE-Q are implemented in future
+-        //data32 = readl(TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-        //if (tp->port_id == 0)
+-              //data32 |= DEFAULT_Q0_INT_BIT;
+-        //else
+-              //data32 |= DEFAULT_Q1_INT_BIT;
+-        //writel(data32, TOE_GLOBAL_BASE + GLOBAL_INTERRUPT_ENABLE_1_REG);
+-              writel(0x3, TOE_GLOBAL_BASE+GLOBAL_INTERRUPT_ENABLE_1_REG);
+-              //printk("\n%s::netif_rx_complete-->  rx_pkts_num =%d,   rwptr.bits.rptr=0x%x,   rwptr.bits.wptr = 0x%x ====---------=======>JKJKJKJKJK\n",
+-              //__func__,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.wptr);
+-        writel(0x07960200, TOE_GMAC0_BASE+GMAC_CONFIG0);
+-              writel(0x07960200, TOE_GMAC1_BASE+GMAC_CONFIG0);
+-        return 0;
+-    }
+-    else
+-    {
+-        //printk("\n%s:: return 1 -->status4= 0x%x,rx_pkts_num =%d,   rwptr.bits.rptr=0x%x,   rwptr.bits.wptr = 0x%x  ======> \n", __func__,status4,rx_pkts_num,rwptr.bits.rptr,rwptr.bits.wptr);
+-        return 1;
+-    }
++              spin_unlock_irqrestore(&gmac_fq_lock, flags);
++
++              return 0;
++      }
++      else
++      {
++              /* not done, will call ->poll() later. */
++              return 1;
++      }
+ }
+ #endif
+@@ -5114,6 +4475,7 @@
+                       {
+                               sl351x_nat_workaround_cnt++;
+                               sl351x_nat_workaround_handler();
++                              printk("%():%d - workaround\n", __func__, __LINE__);
+                       }
+ #endif
+ #endif
+@@ -5124,6 +4486,7 @@
+       }
+ do_workaround:
++      printk("doing workaround ?!\n");
+       gmac_initialized = 0;
+       if (hanged_state)
+@@ -5290,6 +4653,7 @@
+       GMAC_SWTXQ_T    *swtxq;
+       DMA_RWPTR_T             rwptr;
++      printk("**** %s():%d\n", __func__, __LINE__);
+       toe = (TOE_INFO_T *)&toe_private_data;
+       tp = (GMAC_INFO_T *)&toe->gmac[0];
+       for (i=0; i<GMAC_NUM; i++, tp++)
+@@ -5341,6 +4705,7 @@
+       volatile GMAC_RXDESC_T  *curr_desc;
+       struct sk_buff                  *skb;
++      printk("**** %s():%d\n", __func__, __LINE__);
+       toe = (TOE_INFO_T *)&toe_private_data;
+       tp = (GMAC_INFO_T *)&toe->gmac[0];
+       for (i=0; i<GMAC_NUM; i++, tp++)
+@@ -5374,6 +4739,7 @@
+       volatile GMAC_RXDESC_T  *curr_desc;
+       struct sk_buff                  *skb;
++      printk("**** %s():%d\n", __func__, __LINE__);
+       toe = (TOE_INFO_T *)&toe_private_data;
+       classq = (CLASSQ_INFO_T *)&toe->classq[0];
+       for (i=0; i<TOE_CLASS_QUEUE_NUM; i++, classq++)
+@@ -5410,6 +4776,7 @@
+       GMAC_RXDESC_T   *toe_curr_desc;
+       struct sk_buff                  *skb;
++      printk("**** %s():%d\n", __func__, __LINE__);
+       toe = (TOE_INFO_T *)&toe_private_data;
+       toe_qhdr = (TOE_QHDR_T *)TOE_TOE_QUE_HDR_BASE;
+       for (i=0; i<TOE_TOE_QUEUE_NUM; i++, toe_qhdr++)
+--- a/include/asm-arm/arch-sl2312/sl351x_gmac.h
++++ b/include/asm-arm/arch-sl2312/sl351x_gmac.h
+@@ -107,7 +107,7 @@
+  * The base address and descriptor number are configured at
+  * DMA Queues Descriptor Ring Base Address/Size Register (offset 0x0004)
+  **********************************************************************/
+-#define TOE_SW_FREEQ_DESC_POWER               10
++#define TOE_SW_FREEQ_DESC_POWER               8
+ #define TOE_SW_FREEQ_DESC_NUM         (1<<TOE_SW_FREEQ_DESC_POWER)
+ #define TOE_HW_FREEQ_DESC_POWER               8
+ #define TOE_HW_FREEQ_DESC_NUM         (1<<TOE_HW_FREEQ_DESC_POWER)
+@@ -123,12 +123,12 @@
+ #define TOE_DEFAULT_Q0_DESC_NUM               (1<<TOE_DEFAULT_Q0_DESC_POWER)
+ #define TOE_DEFAULT_Q1_DESC_POWER     8
+ #define TOE_DEFAULT_Q1_DESC_NUM               (1<<TOE_DEFAULT_Q1_DESC_POWER)
+-#define TOE_TOE_DESC_POWER                    8
+-#define TOE_TOE_DESC_NUM                      (1<<TOE_TOE_DESC_POWER)
++#define TOE_TOE_DESC_POWER            8
++#define TOE_TOE_DESC_NUM              (1<<TOE_TOE_DESC_POWER)
+ #define TOE_CLASS_DESC_POWER          8
+-#define TOE_CLASS_DESC_NUM                    (1<<TOE_CLASS_DESC_POWER)
+-#define TOE_INTR_DESC_POWER                   8
+-#define TOE_INTR_DESC_NUM                     (1<<TOE_INTR_DESC_POWER)
++#define TOE_CLASS_DESC_NUM            (1<<TOE_CLASS_DESC_POWER)
++#define TOE_INTR_DESC_POWER           8
++#define TOE_INTR_DESC_NUM             (1<<TOE_INTR_DESC_POWER)
+ #define TOE_TOE_QUEUE_MAX                     64
+ #define TOE_TOE_QUEUE_NUM                     64