Index: linux-2.6.23.17/drivers/net/via-velocity.c =================================================================== --- linux-2.6.23.17.orig/drivers/net/via-velocity.c +++ linux-2.6.23.17/drivers/net/via-velocity.c @@ -96,11 +96,31 @@ MODULE_AUTHOR("VIA Networking Technologi MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("VIA Networking Velocity Family Gigabit Ethernet Adapter Driver"); +/* Valid values for vdebug (additive, this is a bitmask): + * 0x00 => off + * 0x01 => always on + * 0x02 => additional detail on tx (rx, too, if anyone implements same) + * 0x04 => detail the initialization process + * 0x08 => spot debug detail; to be used as developers see fit + */ +static int vdebug = 0; + +/* HAIL - these macros are for the normal 0x01-type tracing... */ +#define HAIL(S) \ + if (vdebug&1) printk(KERN_NOTICE "%s\n", (S)); +#define HAILS(S,T) \ + if (vdebug&1) printk(KERN_NOTICE "%s -> status=0x%x\n", (S), (T)); + #define VELOCITY_PARAM(N,D) \ static int N[MAX_UNITS]=OPTION_DEFAULT;\ module_param_array(N, int, NULL, 0); \ MODULE_PARM_DESC(N, D); +#define VELO_DEBUG_MIN 0 +#define VELO_DEBUG_MAX 255 +#define VELO_DEBUG_DEF 0 +VELOCITY_PARAM(velo_debug, "Debug level"); + #define RX_DESC_MIN 64 #define RX_DESC_MAX 255 #define RX_DESC_DEF 64 @@ -385,12 +405,12 @@ static void __devinit velocity_set_int_o if (val == -1) *opt = def; else if (val < min || val > max) { - VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (%d-%d)\n", - devname, name, min, max); + VELOCITY_PRT(MSG_LEVEL_INFO, KERN_NOTICE "via-velocity: the value of parameter %s is invalid, the valid range is (%d-%d)\n", + name, min, max); *opt = def; } else { - VELOCITY_PRT(MSG_LEVEL_INFO, KERN_INFO "%s: set value of parameter %s to %d\n", - devname, name, val); + VELOCITY_PRT(MSG_LEVEL_INFO, KERN_INFO "via-velocity: set value of parameter %s to %d\n", + name, val); *opt = val; } } @@ -415,12 +435,12 @@ static void __devinit velocity_set_bool_ if (val == -1) *opt |= (def ? flag : 0); else if (val < 0 || val > 1) { - printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n", - devname, name); + printk(KERN_NOTICE "via-velocity: the value of parameter %s is invalid, the valid range is (0-1)\n", + name); *opt |= (def ? flag : 0); } else { - printk(KERN_INFO "%s: set parameter %s to %s\n", - devname, name, val ? "TRUE" : "FALSE"); + printk(KERN_INFO "via-velocity: set parameter %s to %s\n", + name, val ? "TRUE" : "FALSE"); *opt |= (val ? flag : 0); } } @@ -438,6 +458,7 @@ static void __devinit velocity_set_bool_ static void __devinit velocity_get_options(struct velocity_opt *opts, int index, char *devname) { + velocity_set_int_opt(&opts->velo_debug, velo_debug[index], VELO_DEBUG_MIN, VELO_DEBUG_MAX, VELO_DEBUG_DEF, "velo_debug", devname); velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname); velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname); velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname); @@ -452,6 +473,7 @@ static void __devinit velocity_get_optio velocity_set_int_opt((int *) &opts->wol_opts, wol_opts[index], WOL_OPT_MIN, WOL_OPT_MAX, WOL_OPT_DEF, "Wake On Lan options", devname); velocity_set_int_opt((int *) &opts->int_works, int_works[index], INT_WORKS_MIN, INT_WORKS_MAX, INT_WORKS_DEF, "Interrupt service works", devname); opts->numrx = (opts->numrx & ~3); + vdebug = opts->velo_debug; } /** @@ -466,6 +488,8 @@ static void velocity_init_cam_filter(str { struct mac_regs __iomem * regs = vptr->mac_regs; + HAIL("velocity_init_cam_filter"); + /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */ WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, ®s->MCFG); WORD_REG_BITS_ON(MCFG_VIDFR, ®s->MCFG); @@ -484,14 +508,12 @@ static void velocity_init_cam_filter(str WORD_REG_BITS_ON(MCFG_RTGOPT, ®s->MCFG); mac_set_cam(regs, 0, (u8 *) & (vptr->options.vid), VELOCITY_VLAN_ID_CAM); - vptr->vCAMmask[0] |= 1; - mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM); } else { u16 temp = 0; mac_set_cam(regs, 0, (u8 *) &temp, VELOCITY_VLAN_ID_CAM); - temp = 1; - mac_set_cam_mask(regs, (u8 *) &temp, VELOCITY_VLAN_ID_CAM); } + vptr->vCAMmask[0] |= 1; + mac_set_cam_mask(regs, vptr->vCAMmask, VELOCITY_VLAN_ID_CAM); } /** @@ -508,13 +530,15 @@ static void velocity_rx_reset(struct vel struct mac_regs __iomem * regs = vptr->mac_regs; int i; + HAIL("velocity_rx_reset"); vptr->rd_dirty = vptr->rd_filled = vptr->rd_curr = 0; /* * Init state, all RD entries belong to the NIC */ for (i = 0; i < vptr->options.numrx; ++i) - vptr->rd_ring[i].rdesc0.owner = OWNED_BY_NIC; + /* vptr->rd_ring[i].rdesc0.owner = OWNED_BY_NIC; BE */ + vptr->rd_ring[i].rdesc0 |= cpu_to_le32(BE_OWNED_BY_NIC); /* BE */ writew(vptr->options.numrx, ®s->RBRDU); writel(vptr->rd_pool_dma, ®s->RDBaseLo); @@ -537,12 +561,15 @@ static void velocity_init_registers(stru struct mac_regs __iomem * regs = vptr->mac_regs; int i, mii_status; + if (vdebug&5) printk(KERN_NOTICE "velocity_init_registers: entering\n"); + mac_wol_reset(regs); switch (type) { case VELOCITY_INIT_RESET: case VELOCITY_INIT_WOL: + if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: RESET or WOL\n"); netif_stop_queue(vptr->dev); /* @@ -570,12 +597,13 @@ static void velocity_init_registers(stru case VELOCITY_INIT_COLD: default: + if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: COLD or default\n"); /* * Do reset */ velocity_soft_reset(vptr); + if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: soft reset complete.\n"); mdelay(5); - mac_eeprom_reload(regs); for (i = 0; i < 6; i++) { writeb(vptr->dev->dev_addr[i], &(regs->PAR[i])); @@ -593,11 +621,16 @@ static void velocity_init_registers(stru */ BYTE_REG_BITS_SET(CFGB_OFSET, (CFGB_CRANDOM | CFGB_CAP | CFGB_MBA | CFGB_BAKOPT), ®s->CFGB); + if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: Initializing CAM filter\n"); /* * Init CAM filter */ + if (vdebug&8) printk(KERN_NOTICE "velocity: spot debug: about to init CAM filters\n"); + mdelay(5); /* MJW - ARM processors, kernel 2.6.19 - this fixes oopses and hangs */ velocity_init_cam_filter(vptr); + if (vdebug&8) printk(KERN_NOTICE "velocity: spot debug: init CAM filters complete\n"); + if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: Setting packet filter\n"); /* * Set packet filter: Receive directed and broadcast address */ @@ -607,10 +640,12 @@ static void velocity_init_registers(stru * Enable MII auto-polling */ enable_mii_autopoll(regs); + if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: enable_mii_autopoll complete.\n"); vptr->int_mask = INT_MASK_DEF; - writel(cpu_to_le32(vptr->rd_pool_dma), ®s->RDBaseLo); + /* writel(cpu_to_le32(vptr->rd_pool_dma), ®s->RDBaseLo); BE */ + writel((vptr->rd_pool_dma), ®s->RDBaseLo); /* BE */ writew(vptr->options.numrx - 1, ®s->RDCSize); mac_rx_queue_run(regs); mac_rx_queue_wake(regs); @@ -618,10 +653,13 @@ static void velocity_init_registers(stru writew(vptr->options.numtx - 1, ®s->TDCSize); for (i = 0; i < vptr->num_txq; i++) { - writel(cpu_to_le32(vptr->td_pool_dma[i]), &(regs->TDBaseLo[i])); + /* writel(cpu_to_le32(vptr->td_pool_dma[i]), &(regs->TDBaseLo[i])); BE */ + writel((vptr->td_pool_dma[i]), &(regs->TDBaseLo[i])); /* BE */ mac_tx_queue_run(regs, i); } + if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: DMA settings complete.\n"); + init_flow_control_register(vptr); writel(CR0_STOP, ®s->CR0Clr); @@ -640,8 +678,10 @@ static void velocity_init_registers(stru enable_flow_control_ability(vptr); mac_hw_mibs_init(regs); + if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: Set interrupt mask\n"); mac_write_int_mask(vptr->int_mask, regs); mac_clear_isr(regs); + if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: complete.\n"); } } @@ -659,6 +699,7 @@ static int velocity_soft_reset(struct ve struct mac_regs __iomem * regs = vptr->mac_regs; int i = 0; + HAIL("velocity_soft_reset"); writel(CR0_SFRST, ®s->CR0Set); for (i = 0; i < W_MAX_TIMEOUT; i++) { @@ -722,6 +763,7 @@ static int __devinit velocity_found1(str VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION); printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n"); printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n"); + printk(KERN_INFO "BE support, misc. fixes MJW 01Jan2007 - may be unstable\n"); first = 0; } @@ -934,6 +976,7 @@ static int velocity_init_rings(struct ve dma_addr_t pool_dma; u8 *pool; + HAIL("velocity_init_rings"); /* * Allocate all RD/TD rings a single pool */ @@ -996,6 +1039,7 @@ static int velocity_init_rings(struct ve static void velocity_free_rings(struct velocity_info *vptr) { int size; + HAIL("velocity_free_rings"); size = vptr->options.numrx * sizeof(struct rx_desc) + vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq; @@ -1012,6 +1056,7 @@ static inline void velocity_give_many_rx struct mac_regs __iomem *regs = vptr->mac_regs; int avail, dirty, unusable; + HAIL("velocity_give_many_rx_descs"); /* * RD number must be equal to 4X per hardware spec * (programming guide rev 1.20, p.13) @@ -1025,7 +1070,8 @@ static inline void velocity_give_many_rx dirty = vptr->rd_dirty - unusable; for (avail = vptr->rd_filled & 0xfffc; avail; avail--) { dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1; - vptr->rd_ring[dirty].rdesc0.owner = OWNED_BY_NIC; + /* vptr->rd_ring[dirty].rdesc0.owner = OWNED_BY_NIC; BE */ + vptr->rd_ring[dirty].rdesc0 |= cpu_to_le32(BE_OWNED_BY_NIC); /* BE */ } writew(vptr->rd_filled & 0xfffc, ®s->RBRDU); @@ -1035,12 +1081,14 @@ static inline void velocity_give_many_rx static int velocity_rx_refill(struct velocity_info *vptr) { int dirty = vptr->rd_dirty, done = 0, ret = 0; + HAIL("velocity_rx_refill"); do { struct rx_desc *rd = vptr->rd_ring + dirty; /* Fine for an all zero Rx desc at init time as well */ - if (rd->rdesc0.owner == OWNED_BY_NIC) + /* if (rd->rdesc0.owner == OWNED_BY_NIC) BE */ + if (rd->rdesc0 & cpu_to_le32(BE_OWNED_BY_NIC)) /* BE */ break; if (!vptr->rd_info[dirty].skb) { @@ -1075,6 +1123,7 @@ static int velocity_init_rd_ring(struct unsigned int rsize = sizeof(struct velocity_rd_info) * vptr->options.numrx; + HAIL("velocity_init_rd_ring"); vptr->rd_info = kmalloc(rsize, GFP_KERNEL); if(vptr->rd_info == NULL) goto out; @@ -1104,6 +1153,7 @@ static void velocity_free_rd_ring(struct { int i; + HAIL("velocity_free_rd_ring"); if (vptr->rd_info == NULL) return; @@ -1145,6 +1195,7 @@ static int velocity_init_td_ring(struct unsigned int tsize = sizeof(struct velocity_td_info) * vptr->options.numtx; + HAIL("velocity_init_td_ring"); /* Init the TD ring entries */ for (j = 0; j < vptr->num_txq; j++) { curr = vptr->td_pool_dma[j]; @@ -1181,6 +1232,7 @@ static void velocity_free_td_ring_entry( struct velocity_td_info * td_info = &(vptr->td_infos[q][n]); int i; + HAIL("velocity_free_td_ring_entry"); if (td_info == NULL) return; @@ -1210,6 +1262,7 @@ static void velocity_free_td_ring(struct { int i, j; + HAIL("velocity_free_td_ring"); for (j = 0; j < vptr->num_txq; j++) { if (vptr->td_infos[j] == NULL) continue; @@ -1237,34 +1290,42 @@ static int velocity_rx_srv(struct veloci struct net_device_stats *stats = &vptr->stats; int rd_curr = vptr->rd_curr; int works = 0; + u16 wRSR; /* BE */ + HAILS("velocity_rx_srv", status); do { struct rx_desc *rd = vptr->rd_ring + rd_curr; if (!vptr->rd_info[rd_curr].skb) break; - if (rd->rdesc0.owner == OWNED_BY_NIC) + /* if (rd->rdesc0.owner == OWNED_BY_NIC) BE */ + if (rd->rdesc0 & cpu_to_le32(BE_OWNED_BY_NIC)) /* BE */ break; rmb(); + wRSR = (u16)(cpu_to_le32(rd->rdesc0)); /* BE */ /* * Don't drop CE or RL error frame although RXOK is off */ - if ((rd->rdesc0.RSR & RSR_RXOK) || (!(rd->rdesc0.RSR & RSR_RXOK) && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) { + /* if ((rd->rdesc0.RSR & RSR_RXOK) || (!(rd->rdesc0.RSR & RSR_RXOK) && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) { BE */ + if ((wRSR & RSR_RXOK) || (!(wRSR & RSR_RXOK) && (wRSR & (RSR_CE | RSR_RL)))) { /* BE */ if (velocity_receive_frame(vptr, rd_curr) < 0) stats->rx_dropped++; } else { - if (rd->rdesc0.RSR & RSR_CRC) + /* if (rd->rdesc0.RSR & RSR_CRC) BE */ + if (wRSR & RSR_CRC) /* BE */ stats->rx_crc_errors++; - if (rd->rdesc0.RSR & RSR_FAE) + /* if (rd->rdesc0.RSR & RSR_FAE) BE */ + if (wRSR & RSR_FAE) /* BE */ stats->rx_frame_errors++; stats->rx_dropped++; } - rd->inten = 1; + /* rd->inten = 1; BE */ + rd->ltwo |= cpu_to_le32(BE_INT_ENABLE); /* BE */ vptr->dev->last_rx = jiffies; @@ -1295,13 +1356,21 @@ static int velocity_rx_srv(struct veloci static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb) { + u8 bCSM; + HAIL("velocity_rx_csum"); skb->ip_summed = CHECKSUM_NONE; - if (rd->rdesc1.CSM & CSM_IPKT) { - if (rd->rdesc1.CSM & CSM_IPOK) { - if ((rd->rdesc1.CSM & CSM_TCPKT) || - (rd->rdesc1.CSM & CSM_UDPKT)) { - if (!(rd->rdesc1.CSM & CSM_TUPOK)) { +// if (rd->rdesc1.CSM & CSM_IPKT) { +// if (rd->rdesc1.CSM & CSM_IPOK) { +// if ((rd->rdesc1.CSM & CSM_TCPKT) || +// (rd->rdesc1.CSM & CSM_UDPKT)) { +// if (!(rd->rdesc1.CSM & CSM_TUPOK)) { + bCSM = (u8)(cpu_to_le32(rd->rdesc1) >> 16); /* BE */ + if (bCSM & CSM_IPKT) { + if (bCSM & CSM_IPOK) { + if ((bCSM & CSM_TCPKT) || + (bCSM & CSM_UDPKT)) { + if (!(bCSM & CSM_TUPOK)) { /* BE */ return; } } @@ -1327,9 +1396,11 @@ static inline int velocity_rx_copy(struc { int ret = -1; + HAIL("velocity_rx_copy"); if (pkt_size < rx_copybreak) { struct sk_buff *new_skb; + HAIL("velocity_rx_copy (working...)"); new_skb = dev_alloc_skb(pkt_size + 2); if (new_skb) { new_skb->dev = vptr->dev; @@ -1360,10 +1431,12 @@ static inline int velocity_rx_copy(struc static inline void velocity_iph_realign(struct velocity_info *vptr, struct sk_buff *skb, int pkt_size) { + HAIL("velocity_iph_realign"); /* FIXME - memmove ? */ if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) { int i; + HAIL("velocity_iph_realign (working...)"); for (i = pkt_size; i >= 0; i--) *(skb->data + i + 2) = *(skb->data + i); skb_reserve(skb, 2); @@ -1382,19 +1455,27 @@ static inline void velocity_iph_realign( static int velocity_receive_frame(struct velocity_info *vptr, int idx) { void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int); + u16 pkt_len; /* BE */ + u16 wRSR; /* BE */ + struct sk_buff *skb; struct net_device_stats *stats = &vptr->stats; struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]); struct rx_desc *rd = &(vptr->rd_ring[idx]); - int pkt_len = rd->rdesc0.len; - struct sk_buff *skb; + /* int pkt_len = rd->rdesc0.len BE */; + + pkt_len = ((cpu_to_le32(rd->rdesc0) >> 16) & 0x00003FFFUL); /* BE */ + wRSR = (u16)(cpu_to_le32(rd->rdesc0)); /* BE */ - if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) { + HAIL("velocity_receive_frame"); + /* if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) { BE */ + if (wRSR & (RSR_STP | RSR_EDP)) { /* BE */ VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name); stats->rx_length_errors++; return -EINVAL; } - if (rd->rdesc0.RSR & RSR_MAR) + /* if (rd->rdesc0.RSR & RSR_MAR) BE */ + if (wRSR & RSR_MAR) /* BE */ vptr->stats.multicast++; skb = rd_info->skb; @@ -1407,7 +1488,8 @@ static int velocity_receive_frame(struct */ if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) { - if (rd->rdesc0.RSR & RSR_RL) { + /* if (rd->rdesc0.RSR & RSR_RL) { BE */ + if (wRSR & RSR_RL) { /* BE */ stats->rx_length_errors++; return -EINVAL; } @@ -1451,6 +1533,7 @@ static int velocity_alloc_rx_buf(struct struct rx_desc *rd = &(vptr->rd_ring[idx]); struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]); + HAIL("velocity_alloc_rx_buf"); rd_info->skb = dev_alloc_skb(vptr->rx_buf_sz + 64); if (rd_info->skb == NULL) return -ENOMEM; @@ -1468,10 +1551,14 @@ static int velocity_alloc_rx_buf(struct */ *((u32 *) & (rd->rdesc0)) = 0; - rd->len = cpu_to_le32(vptr->rx_buf_sz); - rd->inten = 1; + /* rd->len = cpu_to_le32(vptr->rx_buf_sz); BE */ + /* rd->inten = 1; BE */ rd->pa_low = cpu_to_le32(rd_info->skb_dma); - rd->pa_high = 0; + /* rd->pa_high = 0; BE */ + rd->ltwo &= cpu_to_le32(0xC000FFFFUL); /* BE */ + rd->ltwo |= cpu_to_le32((vptr->rx_buf_sz << 16)); /* BE */ + rd->ltwo |= cpu_to_le32(BE_INT_ENABLE); /* BE */ + rd->ltwo &= cpu_to_le32(0xFFFF0000UL); /* BE */ return 0; } @@ -1492,9 +1579,11 @@ static int velocity_tx_srv(struct veloci int full = 0; int idx; int works = 0; + u16 wTSR; /* BE */ struct velocity_td_info *tdinfo; struct net_device_stats *stats = &vptr->stats; + HAILS("velocity_tx_srv", status); for (qnum = 0; qnum < vptr->num_txq; qnum++) { for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0; idx = (idx + 1) % vptr->options.numtx) { @@ -1505,22 +1594,29 @@ static int velocity_tx_srv(struct veloci td = &(vptr->td_rings[qnum][idx]); tdinfo = &(vptr->td_infos[qnum][idx]); - if (td->tdesc0.owner == OWNED_BY_NIC) + /* if (td->tdesc0.owner == OWNED_BY_NIC) BE */ + if (td->tdesc0 & cpu_to_le32(BE_OWNED_BY_NIC)) /* BE */ break; if ((works++ > 15)) break; - if (td->tdesc0.TSR & TSR0_TERR) { + wTSR = (u16)cpu_to_le32(td->tdesc0); + /* if (td->tdesc0.TSR & TSR0_TERR) { BE */ + if (wTSR & TSR0_TERR) { /* BE */ stats->tx_errors++; stats->tx_dropped++; - if (td->tdesc0.TSR & TSR0_CDH) + /* if (td->tdesc0.TSR & TSR0_CDH) BE */ + if (wTSR & TSR0_CDH) /* BE */ stats->tx_heartbeat_errors++; - if (td->tdesc0.TSR & TSR0_CRS) + /* if (td->tdesc0.TSR & TSR0_CRS) BE */ + if (wTSR & TSR0_CRS) /* BE */ stats->tx_carrier_errors++; - if (td->tdesc0.TSR & TSR0_ABT) + /* if (td->tdesc0.TSR & TSR0_ABT) BE */ + if (wTSR & TSR0_ABT) /* BE */ stats->tx_aborted_errors++; - if (td->tdesc0.TSR & TSR0_OWC) + /* if (td->tdesc0.TSR & TSR0_OWC) BE */ + if (wTSR & TSR0_OWC) /* BE */ stats->tx_window_errors++; } else { stats->tx_packets++; @@ -1609,6 +1705,7 @@ static void velocity_print_link_status(s static void velocity_error(struct velocity_info *vptr, int status) { + HAILS("velocity_error", status); if (status & ISR_TXSTLI) { struct mac_regs __iomem * regs = vptr->mac_regs; @@ -1698,6 +1795,7 @@ static void velocity_free_tx_buf(struct struct sk_buff *skb = tdinfo->skb; int i; + HAIL("velocity_free_tx_buf"); /* * Don't unmap the pre-allocated tx_bufs */ @@ -1901,6 +1999,7 @@ static int velocity_xmit(struct sk_buff struct velocity_td_info *tdinfo; unsigned long flags; int index; + u32 lbufsz; /* BE */ int pktlen = skb->len; @@ -1917,9 +2016,18 @@ static int velocity_xmit(struct sk_buff td_ptr = &(vptr->td_rings[qnum][index]); tdinfo = &(vptr->td_infos[qnum][index]); - td_ptr->tdesc1.TCPLS = TCPLS_NORMAL; - td_ptr->tdesc1.TCR = TCR0_TIC; - td_ptr->td_buf[0].queue = 0; + td_ptr->tdesc0 = 0x00000000UL; /* BE */ + td_ptr->tdesc1 = 0x00000000UL; /* BE */ + + /* td_ptr->tdesc1.TCPLS = TCPLS_NORMAL; BE */ + td_ptr->tdesc1 &= cpu_to_le32(0xfcffffffUL); /* BE */ + td_ptr->tdesc1 |= cpu_to_le32(((u32)TCPLS_NORMAL) << 24); /* BE */ + + /* td_ptr->tdesc1.TCR = TCR0_TIC; BE */ + td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_TIC); /* BE */ + + /* td_ptr->td_buf[0].queue = 0; BE */ + td_ptr->td_buf[0].ltwo &= cpu_to_le32(~BE_QUEUE_ENABLE); /* BE */ /* * Pad short frames. @@ -1931,20 +2039,36 @@ static int velocity_xmit(struct sk_buff memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len); tdinfo->skb = skb; tdinfo->skb_dma[0] = tdinfo->buf_dma; - td_ptr->tdesc0.pktsize = pktlen; + /* td_ptr->tdesc0.pktsize = pktlen; */ + td_ptr->tdesc0 &= cpu_to_le32(0xc000ffffUL); /* BE */ + lbufsz = pktlen; /* Assign, and make sure it's unsigned 32 bits - BE */ + lbufsz = lbufsz << 16; /* BE - shift over */ + td_ptr->tdesc0 |= cpu_to_le32(lbufsz); /* BE */ + td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]); - td_ptr->td_buf[0].pa_high = 0; - td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize; + /* td_ptr->td_buf[0].pa_high = 0; */ + /* td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize; */ + td_ptr->td_buf[0].ltwo = cpu_to_le32(lbufsz); /* BE */ tdinfo->nskb_dma = 1; - td_ptr->tdesc1.CMDZ = 2; + /* td_ptr->tdesc1.CMDZ = 2; */ + td_ptr->tdesc1 &= cpu_to_le32(0x0fffffffUL); /* BE */ + td_ptr->tdesc1 |= cpu_to_le32(((u32)0x2) << 28); /* BE */ } else #ifdef VELOCITY_ZERO_COPY_SUPPORT + /* + * BE - NOTE on the VELOCITY_ZERO_COPY_SUPPORT: + * This block of code has NOT been patched up for BE support, as + * it is certainly broken -- if it compiles at all. Since the BE + * fixes depend on the broken code, attempts to convert to BE support + * would almost certainly confuse more than help. + */ if (skb_shinfo(skb)->nr_frags > 0) { int nfrags = skb_shinfo(skb)->nr_frags; tdinfo->skb = skb; if (nfrags > 6) { skb_copy_from_linear_data(skb, tdinfo->buf, skb->len); tdinfo->skb_dma[0] = tdinfo->buf_dma; + /* BE: Er, exactly what value are we assigning in this next line? */ td_ptr->tdesc0.pktsize = td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]); td_ptr->td_buf[0].pa_high = 0; @@ -1961,6 +2085,7 @@ static int velocity_xmit(struct sk_buff /* FIXME: support 48bit DMA later */ td_ptr->td_buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma); td_ptr->td_buf[i].pa_high = 0; + /* BE: This next line can't be right: */ td_ptr->td_buf[i].bufsize = skb->len->skb->data_len; for (i = 0; i < nfrags; i++) { @@ -1978,7 +2103,7 @@ static int velocity_xmit(struct sk_buff } } else -#endif +#endif /* (broken) VELOCITY_ZERO_COPY_SUPPORT */ { /* * Map the linear network buffer into PCI space and @@ -1986,19 +2111,30 @@ static int velocity_xmit(struct sk_buff */ tdinfo->skb = skb; tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE); - td_ptr->tdesc0.pktsize = pktlen; + /* td_ptr->tdesc0.pktsize = pktlen; BE */ + td_ptr->tdesc0 &= cpu_to_le32(0xc000ffffUL); /* BE */ + lbufsz = pktlen; /* Assign, and make sure it's unsigned 32 bits - BE */ + lbufsz = lbufsz << 16; /* BE */ + td_ptr->tdesc0 |= cpu_to_le32(lbufsz); /* BE */ td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]); - td_ptr->td_buf[0].pa_high = 0; - td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize; + /* td_ptr->td_buf[0].pa_high = 0; BE */ + /* td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize; BE */ + td_ptr->td_buf[0].ltwo = cpu_to_le32(lbufsz); /* BE */ + tdinfo->nskb_dma = 1; - td_ptr->tdesc1.CMDZ = 2; + /* td_ptr->tdesc1.CMDZ = 2; BE */ + td_ptr->tdesc1 &= cpu_to_le32(0x0fffffffUL); /* BE */ + td_ptr->tdesc1 |= cpu_to_le32(((u32)0x2) << 28);/* BE */ } if (vptr->flags & VELOCITY_FLAGS_TAGGING) { - td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff); - td_ptr->tdesc1.pqinf.priority = 0; - td_ptr->tdesc1.pqinf.CFI = 0; - td_ptr->tdesc1.TCR |= TCR0_VETAG; + /* td_ptr->tdesc1.pqinf.priority = 0; BE */ + /* td_ptr->tdesc1.pqinf.CFI = 0; BE */ + td_ptr->tdesc1 &= cpu_to_le32(0xFFFF0000UL); /* BE */ + /* td_ptr->tdesc1.pqinf.VID = (vptr->options.vid & 0xfff); BE */ + td_ptr->tdesc1 |= cpu_to_le32((vptr->options.vid & 0xfff)); /* BE */ + /* td_ptr->tdesc1.TCR |= TCR0_VETAG; BE */ + td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_VETAG); /* BE */ } /* @@ -2008,26 +2144,34 @@ static int velocity_xmit(struct sk_buff && (skb->ip_summed == CHECKSUM_PARTIAL)) { const struct iphdr *ip = ip_hdr(skb); if (ip->protocol == IPPROTO_TCP) - td_ptr->tdesc1.TCR |= TCR0_TCPCK; + /* td_ptr->tdesc1.TCR |= TCR0_TCPCK; BE */ + td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_TCPCK); /* BE */ else if (ip->protocol == IPPROTO_UDP) - td_ptr->tdesc1.TCR |= (TCR0_UDPCK); - td_ptr->tdesc1.TCR |= TCR0_IPCK; - } + /* td_ptr->tdesc1.TCR |= (TCR0_UDPCK); BE */ + td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_UDPCK); /* BE */ + /* td_ptr->tdesc1.TCR |= TCR0_IPCK; BE */ + td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_IPCK); /* BE */ + } { int prev = index - 1; if (prev < 0) prev = vptr->options.numtx - 1; - td_ptr->tdesc0.owner = OWNED_BY_NIC; + /* td_ptr->tdesc0.owner = OWNED_BY_NIC; BE */ + td_ptr->tdesc0 |= cpu_to_le32(BE_OWNED_BY_NIC); /* BE */ vptr->td_used[qnum]++; vptr->td_curr[qnum] = (index + 1) % vptr->options.numtx; if (AVAIL_TD(vptr, qnum) < 1) netif_stop_queue(dev); - td_ptr = &(vptr->td_rings[qnum][prev]); - td_ptr->td_buf[0].queue = 1; + td_ptr = &(vptr->td_rings[qnum][prev]); + /* td_ptr->td_buf[0].queue = 1; BE */ + td_ptr->td_buf[0].ltwo |= cpu_to_le32(BE_QUEUE_ENABLE); /* BE */ + if (vdebug&2) printk(KERN_NOTICE "velocity_xmit: (%s) len=%d idx=%d tdesc0=0x%x tdesc1=0x%x ltwo=0x%x\n", + (pktlentdesc0, td_ptr->tdesc1, td_ptr->td_buf[0].ltwo); mac_tx_queue_wake(vptr->mac_regs, qnum); } dev->trans_start = jiffies; @@ -2053,7 +2197,7 @@ static int velocity_intr(int irq, void * u32 isr_status; int max_count = 0; - + HAIL("velocity_intr"); spin_lock(&vptr->lock); isr_status = mac_read_isr(vptr->mac_regs); @@ -2072,7 +2216,10 @@ static int velocity_intr(int irq, void * while (isr_status != 0) { mac_write_isr(vptr->mac_regs, isr_status); - if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI))) + HAILS("velocity_intr",isr_status); + /* MJW - velocity_error is ALWAYS called; need to mask off some other flags */ + /* if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI))) */ + if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI | ISR_PTX0I | ISR_ISR0))) velocity_error(vptr, isr_status); if (isr_status & (ISR_PRXI | ISR_PPRXI)) max_count += velocity_rx_srv(vptr, isr_status); @@ -2110,6 +2257,7 @@ static void velocity_set_multi(struct ne int i; struct dev_mc_list *mclist; + HAIL("velocity_set_multi"); if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */ writel(0xffffffff, ®s->MARCAM[0]); writel(0xffffffff, ®s->MARCAM[4]); @@ -2153,6 +2301,7 @@ static struct net_device_stats *velocity { struct velocity_info *vptr = netdev_priv(dev); + HAIL("net_device_stats"); /* If the hardware is down, don't touch MII */ if(!netif_running(dev)) return &vptr->stats; @@ -2197,6 +2346,7 @@ static int velocity_ioctl(struct net_dev struct velocity_info *vptr = netdev_priv(dev); int ret; + HAIL("velocity_ioctl"); /* If we are asked for information and the device is power saving then we need to bring the device back up to talk to it */ @@ -2415,6 +2565,7 @@ static int velocity_mii_read(struct mac_ { u16 ww; + HAIL("velocity_mii_read"); /* * Disable MIICR_MAUTO, so that mii addr can be set normally */ @@ -2451,6 +2602,7 @@ static int velocity_mii_write(struct mac { u16 ww; + HAIL("velocity_mii_write"); /* * Disable MIICR_MAUTO, so that mii addr can be set normally */ Index: linux-2.6.23.17/drivers/net/via-velocity.h =================================================================== --- linux-2.6.23.17.orig/drivers/net/via-velocity.h +++ linux-2.6.23.17/drivers/net/via-velocity.h @@ -196,64 +196,70 @@ * Receive descriptor */ -struct rdesc0 { - u16 RSR; /* Receive status */ - u16 len:14; /* Received packet length */ - u16 reserved:1; - u16 owner:1; /* Who owns this buffer ? */ -}; - -struct rdesc1 { - u16 PQTAG; - u8 CSM; - u8 IPKT; -}; +//struct rdesc0 { +// u16 RSR; /* Receive status */ +// u16 len:14; /* Received packet length */ +// u16 reserved:1; +// u16 owner:1; /* Who owns this buffer ? */ +//}; + +//struct rdesc1 { +// u16 PQTAG; +// u8 CSM; +// u8 IPKT; +//}; struct rx_desc { - struct rdesc0 rdesc0; - struct rdesc1 rdesc1; +// struct rdesc0 rdesc0; +// struct rdesc1 rdesc1; + u32 rdesc0; + u32 rdesc1; u32 pa_low; /* Low 32 bit PCI address */ - u16 pa_high; /* Next 16 bit PCI address (48 total) */ - u16 len:15; /* Frame size */ - u16 inten:1; /* Enable interrupt */ +// u16 pa_high; /* Next 16 bit PCI address (48 total) */ +// u16 len:15; /* Frame size */ +// u16 inten:1; /* Enable interrupt */ + u32 ltwo; } __attribute__ ((__packed__)); /* * Transmit descriptor */ -struct tdesc0 { - u16 TSR; /* Transmit status register */ - u16 pktsize:14; /* Size of frame */ - u16 reserved:1; - u16 owner:1; /* Who owns the buffer */ -}; - -struct pqinf { /* Priority queue info */ - u16 VID:12; - u16 CFI:1; - u16 priority:3; -} __attribute__ ((__packed__)); - -struct tdesc1 { - struct pqinf pqinf; - u8 TCR; - u8 TCPLS:2; - u8 reserved:2; - u8 CMDZ:4; -} __attribute__ ((__packed__)); +//struct tdesc0 { +// u16 TSR; /* Transmit status register */ +// u16 pktsize:14; /* Size of frame */ +// u16 reserved:1; +// u16 owner:1; /* Who owns the buffer */ +//}; + +//struct pqinf { /* Priority queue info */ +// u16 VID:12; +// u16 CFI:1; +// u16 priority:3; +//} __attribute__ ((__packed__)); + +//struct tdesc1 { +// struct pqinf pqinf; +// u8 TCR; +// u8 TCPLS:2; +// u8 reserved:2; +// u8 CMDZ:4; +//} __attribute__ ((__packed__)); struct td_buf { u32 pa_low; - u16 pa_high; - u16 bufsize:14; - u16 reserved:1; - u16 queue:1; +// u16 pa_high; +// u16 bufsize:14; +// u16 reserved:1; +// u16 queue:1; + u32 ltwo; } __attribute__ ((__packed__)); struct tx_desc { - struct tdesc0 tdesc0; - struct tdesc1 tdesc1; +// struct tdesc0 tdesc0; +// struct tdesc1 tdesc1; + u32 tdesc0; + u32 tdesc1; struct td_buf td_buf[7]; }; @@ -279,6 +285,16 @@ enum velocity_owner { OWNED_BY_NIC = 1 }; +/* Constants added for the BE fixes */ +#define BE_OWNED_BY_NIC 0x80000000UL +#define BE_INT_ENABLE 0x80000000UL +#define BE_QUEUE_ENABLE 0x80000000UL +#define BE_TCR_TIC 0x00800000UL +#define BE_TCR_VETAG 0x00200000UL +#define BE_TCR_TCPCK 0x00040000UL +#define BE_TCR_UDPCK 0x00080000UL +#define BE_TCR_IPCK 0x00100000UL + /* * MAC registers and macros. @@ -1698,6 +1714,7 @@ enum velocity_flow_cntl_type { }; struct velocity_opt { + int velo_debug; /* debug flag */ int numrx; /* Number of RX descriptors */ int numtx; /* Number of TX descriptors */ enum speed_opt spd_dpx; /* Media link mode */