diff options
author | Imre Kaloz <kaloz@openwrt.org> | 2008-04-27 17:03:01 +0000 |
---|---|---|
committer | Imre Kaloz <kaloz@openwrt.org> | 2008-04-27 17:03:01 +0000 |
commit | a4dd1adf4a718f4eec35a561be068e2e8f885ae2 (patch) | |
tree | ac861981b1df2200cf8c304636c7c4cd59ac3df9 /target/linux/storm/patches/1006-gmac-napi-tx.patch | |
parent | 261802269dd138d350a124aacc0900d60c800671 (diff) | |
download | upstream-a4dd1adf4a718f4eec35a561be068e2e8f885ae2.tar.gz upstream-a4dd1adf4a718f4eec35a561be068e2e8f885ae2.tar.bz2 upstream-a4dd1adf4a718f4eec35a561be068e2e8f885ae2.zip |
add preliminary support for Storm SL3512 based devices, not ready yet
SVN-Revision: 10956
Diffstat (limited to 'target/linux/storm/patches/1006-gmac-napi-tx.patch')
-rw-r--r-- | target/linux/storm/patches/1006-gmac-napi-tx.patch | 2098 |
1 files changed, 2098 insertions, 0 deletions
diff --git a/target/linux/storm/patches/1006-gmac-napi-tx.patch b/target/linux/storm/patches/1006-gmac-napi-tx.patch new file mode 100644 index 0000000000..7ba63b85a1 --- /dev/null +++ b/target/linux/storm/patches/1006-gmac-napi-tx.patch @@ -0,0 +1,2098 @@ +Index: linux-2.6.23.16/drivers/net/sl351x_gmac.c +=================================================================== +--- linux-2.6.23.16.orig/drivers/net/sl351x_gmac.c 2008-03-15 17:00:55.366700383 +0200 ++++ linux-2.6.23.16/drivers/net/sl351x_gmac.c 2008-03-15 17:01:08.367441241 +0200 +@@ -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++) +Index: linux-2.6.23.16/include/asm-arm/arch-sl2312/sl351x_gmac.h +=================================================================== +--- linux-2.6.23.16.orig/include/asm-arm/arch-sl2312/sl351x_gmac.h 2008-03-15 17:00:21.364762892 +0200 ++++ linux-2.6.23.16/include/asm-arm/arch-sl2312/sl351x_gmac.h 2008-03-15 17:01:08.367441241 +0200 +@@ -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 |