[ixp4xx] refresh kernel patches
[openwrt.git] / target / linux / ixp4xx / patches-2.6.24 / 033-velocity_be.patch
1 Index: linux-2.6.24.7/drivers/net/via-velocity.c
2 ===================================================================
3 --- linux-2.6.24.7.orig/drivers/net/via-velocity.c
4 +++ linux-2.6.24.7/drivers/net/via-velocity.c
5 @@ -254,11 +254,31 @@ MODULE_AUTHOR("VIA Networking Technologi
6  MODULE_LICENSE("GPL");
7  MODULE_DESCRIPTION("VIA Networking Velocity Family Gigabit Ethernet Adapter Driver");
8  
9 +/* Valid values for vdebug (additive, this is a bitmask):
10 + *  0x00 => off
11 + *  0x01 => always on
12 + *  0x02 => additional detail on tx (rx, too, if anyone implements same)
13 + *  0x04 => detail the initialization process
14 + *  0x08 => spot debug detail; to be used as developers see fit
15 + */
16 +static int vdebug = 0;
17 +
18 +/* HAIL - these macros are for the normal 0x01-type tracing... */
19 +#define HAIL(S) \
20 +       if (vdebug&1) printk(KERN_NOTICE "%s\n", (S));
21 +#define HAILS(S,T) \
22 +       if (vdebug&1) printk(KERN_NOTICE "%s -> status=0x%x\n", (S), (T));
23 +
24  #define VELOCITY_PARAM(N,D) \
25          static int N[MAX_UNITS]=OPTION_DEFAULT;\
26         module_param_array(N, int, NULL, 0); \
27          MODULE_PARM_DESC(N, D);
28  
29 +#define VELO_DEBUG_MIN   0
30 +#define VELO_DEBUG_MAX   255
31 +#define VELO_DEBUG_DEF   0
32 +VELOCITY_PARAM(velo_debug, "Debug level");
33 +
34  #define RX_DESC_MIN     64
35  #define RX_DESC_MAX     255
36  #define RX_DESC_DEF     64
37 @@ -557,12 +577,12 @@ static void __devinit velocity_set_bool_
38         if (val == -1)
39                 *opt |= (def ? flag : 0);
40         else if (val < 0 || val > 1) {
41 -               printk(KERN_NOTICE "%s: the value of parameter %s is invalid, the valid range is (0-1)\n",
42 -                       devname, name);
43 +               printk(KERN_NOTICE "via-velocity: the value of parameter %s is invalid, the valid range is (0-1)\n",
44 +                       name);
45                 *opt |= (def ? flag : 0);
46         } else {
47 -               printk(KERN_INFO "%s: set parameter %s to %s\n",
48 -                       devname, name, val ? "TRUE" : "FALSE");
49 +               printk(KERN_INFO "via-velocity: set parameter %s to %s\n",
50 +                       name, val ? "TRUE" : "FALSE");
51                 *opt |= (val ? flag : 0);
52         }
53  }
54 @@ -580,6 +600,7 @@ static void __devinit velocity_set_bool_
55  static void __devinit velocity_get_options(struct velocity_opt *opts, int index, char *devname)
56  {
57  
58 +       velocity_set_int_opt(&opts->velo_debug, velo_debug[index], VELO_DEBUG_MIN, VELO_DEBUG_MAX, VELO_DEBUG_DEF, "velo_debug", devname);
59         velocity_set_int_opt(&opts->rx_thresh, rx_thresh[index], RX_THRESH_MIN, RX_THRESH_MAX, RX_THRESH_DEF, "rx_thresh", devname);
60         velocity_set_int_opt(&opts->DMA_length, DMA_length[index], DMA_LENGTH_MIN, DMA_LENGTH_MAX, DMA_LENGTH_DEF, "DMA_length", devname);
61         velocity_set_int_opt(&opts->numrx, RxDescriptors[index], RX_DESC_MIN, RX_DESC_MAX, RX_DESC_DEF, "RxDescriptors", devname);
62 @@ -593,6 +614,7 @@ static void __devinit velocity_get_optio
63         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);
64         velocity_set_int_opt((int *) &opts->int_works, int_works[index], INT_WORKS_MIN, INT_WORKS_MAX, INT_WORKS_DEF, "Interrupt service works", devname);
65         opts->numrx = (opts->numrx & ~3);
66 +       vdebug = opts->velo_debug;
67  }
68  
69  /**
70 @@ -608,6 +630,8 @@ static void velocity_init_cam_filter(str
71         struct mac_regs __iomem * regs = vptr->mac_regs;
72         unsigned short vid;
73  
74 +       HAIL("velocity_init_cam_filter");
75 +
76         /* Turn on MCFG_PQEN, turn off MCFG_RTGOPT */
77         WORD_REG_BITS_SET(MCFG_PQEN, MCFG_RTGOPT, &regs->MCFG);
78         WORD_REG_BITS_ON(MCFG_VIDFR, &regs->MCFG);
79 @@ -636,8 +660,10 @@ static void velocity_init_cam_filter(str
80         } else {
81                 u16 temp = 0;
82                 mac_set_vlan_cam(regs, 0, (u8 *) &temp);
83 -               temp = 1;
84 -               mac_set_vlan_cam_mask(regs, (u8 *) &temp);
85 +               /* temp = 1;                                    BE */
86 +               /* mac_set_vlan_cam_mask(regs, (u8 *) &temp);   BE */
87 +               vptr->vCAMmask[0] |= 1;                      /* BE */
88 +               mac_set_vlan_cam_mask(regs, vptr->vCAMmask); /* BE */
89         }
90  }
91  
92 @@ -675,13 +701,15 @@ static void velocity_rx_reset(struct vel
93         struct mac_regs __iomem * regs = vptr->mac_regs;
94         int i;
95  
96 +       HAIL("velocity_rx_reset");
97         vptr->rd_dirty = vptr->rd_filled = vptr->rd_curr = 0;
98  
99         /*
100          *      Init state, all RD entries belong to the NIC
101          */
102         for (i = 0; i < vptr->options.numrx; ++i)
103 -               vptr->rd_ring[i].rdesc0.owner = OWNED_BY_NIC;
104 +               /* vptr->rd_ring[i].rdesc0.owner = OWNED_BY_NIC; BE */
105 +               vptr->rd_ring[i].rdesc0 |= cpu_to_le32(BE_OWNED_BY_NIC); /* BE */
106  
107         writew(vptr->options.numrx, &regs->RBRDU);
108         writel(vptr->rd_pool_dma, &regs->RDBaseLo);
109 @@ -704,12 +732,15 @@ static void velocity_init_registers(stru
110         struct mac_regs __iomem * regs = vptr->mac_regs;
111         int i, mii_status;
112  
113 +       if (vdebug&5) printk(KERN_NOTICE "velocity_init_registers: entering\n");
114 +
115         mac_wol_reset(regs);
116  
117         switch (type) {
118         case VELOCITY_INIT_RESET:
119         case VELOCITY_INIT_WOL:
120  
121 +               if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: RESET or WOL\n");
122                 netif_stop_queue(vptr->dev);
123  
124                 /*
125 @@ -737,12 +768,13 @@ static void velocity_init_registers(stru
126  
127         case VELOCITY_INIT_COLD:
128         default:
129 +               if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: COLD or default\n");
130                 /*
131                  *      Do reset
132                  */
133                 velocity_soft_reset(vptr);
134 +               if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: soft reset complete.\n");
135                 mdelay(5);
136 -
137                 mac_eeprom_reload(regs);
138                 for (i = 0; i < 6; i++) {
139                         writeb(vptr->dev->dev_addr[i], &(regs->PAR[i]));
140 @@ -760,11 +792,16 @@ static void velocity_init_registers(stru
141                  */
142                 BYTE_REG_BITS_SET(CFGB_OFSET, (CFGB_CRANDOM | CFGB_CAP | CFGB_MBA | CFGB_BAKOPT), &regs->CFGB);
143  
144 +               if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: Initializing CAM filter\n");
145                 /*
146                  *      Init CAM filter
147                  */
148 +               if (vdebug&8) printk(KERN_NOTICE "velocity: spot debug: about to init CAM filters\n");
149 +               mdelay(5);  /* MJW - ARM processors, kernel 2.6.19 - this fixes oopses and hangs */
150                 velocity_init_cam_filter(vptr);
151 +               if (vdebug&8) printk(KERN_NOTICE "velocity: spot debug: init CAM filters complete\n");
152  
153 +               if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: Setting packet filter\n");
154                 /*
155                  *      Set packet filter: Receive directed and broadcast address
156                  */
157 @@ -774,10 +811,12 @@ static void velocity_init_registers(stru
158                  *      Enable MII auto-polling
159                  */
160                 enable_mii_autopoll(regs);
161 +               if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: enable_mii_autopoll complete.\n");
162  
163                 vptr->int_mask = INT_MASK_DEF;
164  
165 -               writel(cpu_to_le32(vptr->rd_pool_dma), &regs->RDBaseLo);
166 +               /* writel(cpu_to_le32(vptr->rd_pool_dma), &regs->RDBaseLo); BE */
167 +               writel((vptr->rd_pool_dma), &regs->RDBaseLo); /* BE */
168                 writew(vptr->options.numrx - 1, &regs->RDCSize);
169                 mac_rx_queue_run(regs);
170                 mac_rx_queue_wake(regs);
171 @@ -785,10 +824,13 @@ static void velocity_init_registers(stru
172                 writew(vptr->options.numtx - 1, &regs->TDCSize);
173  
174                 for (i = 0; i < vptr->num_txq; i++) {
175 -                       writel(cpu_to_le32(vptr->td_pool_dma[i]), &(regs->TDBaseLo[i]));
176 +                       /* writel(cpu_to_le32(vptr->td_pool_dma[i]), &(regs->TDBaseLo[i])); BE */
177 +                       writel((vptr->td_pool_dma[i]), &(regs->TDBaseLo[i])); /* BE */
178                         mac_tx_queue_run(regs, i);
179                 }
180  
181 +               if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: DMA settings complete.\n");
182 +
183                 init_flow_control_register(vptr);
184  
185                 writel(CR0_STOP, &regs->CR0Clr);
186 @@ -807,8 +849,10 @@ static void velocity_init_registers(stru
187  
188                 enable_flow_control_ability(vptr);
189                 mac_hw_mibs_init(regs);
190 +               if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: Set interrupt mask\n");
191                 mac_write_int_mask(vptr->int_mask, regs);
192                 mac_clear_isr(regs);
193 +               if (vdebug&4) printk(KERN_NOTICE "velocity_init_registers: complete.\n");
194  
195         }
196  }
197 @@ -826,6 +870,7 @@ static int velocity_soft_reset(struct ve
198         struct mac_regs __iomem * regs = vptr->mac_regs;
199         int i = 0;
200  
201 +       HAIL("velocity_soft_reset");
202         writel(CR0_SFRST, &regs->CR0Set);
203  
204         for (i = 0; i < W_MAX_TIMEOUT; i++) {
205 @@ -888,6 +933,7 @@ static int __devinit velocity_found1(str
206                         VELOCITY_FULL_DRV_NAM, VELOCITY_VERSION);
207                 printk(KERN_INFO "Copyright (c) 2002, 2003 VIA Networking Technologies, Inc.\n");
208                 printk(KERN_INFO "Copyright (c) 2004 Red Hat Inc.\n");
209 +               printk(KERN_INFO "BE support, misc. fixes MJW 01Jan2007 - may be unstable\n");
210                 first = 0;
211         }
212  
213 @@ -1104,6 +1150,7 @@ static int velocity_init_rings(struct ve
214         dma_addr_t pool_dma;
215         u8 *pool;
216  
217 +       HAIL("velocity_init_rings");
218         /*
219          *      Allocate all RD/TD rings a single pool
220          */
221 @@ -1166,6 +1213,7 @@ static int velocity_init_rings(struct ve
222  static void velocity_free_rings(struct velocity_info *vptr)
223  {
224         int size;
225 +       HAIL("velocity_free_rings");
226  
227         size = vptr->options.numrx * sizeof(struct rx_desc) +
228                vptr->options.numtx * sizeof(struct tx_desc) * vptr->num_txq;
229 @@ -1182,6 +1230,7 @@ static inline void velocity_give_many_rx
230         struct mac_regs __iomem *regs = vptr->mac_regs;
231         int avail, dirty, unusable;
232  
233 +       HAIL("velocity_give_many_rx_descs");
234         /*
235          * RD number must be equal to 4X per hardware spec
236          * (programming guide rev 1.20, p.13)
237 @@ -1195,7 +1244,8 @@ static inline void velocity_give_many_rx
238         dirty = vptr->rd_dirty - unusable;
239         for (avail = vptr->rd_filled & 0xfffc; avail; avail--) {
240                 dirty = (dirty > 0) ? dirty - 1 : vptr->options.numrx - 1;
241 -               vptr->rd_ring[dirty].rdesc0.owner = OWNED_BY_NIC;
242 +               /* vptr->rd_ring[dirty].rdesc0.owner = OWNED_BY_NIC; BE */
243 +               vptr->rd_ring[dirty].rdesc0 |= cpu_to_le32(BE_OWNED_BY_NIC); /* BE */
244         }
245  
246         writew(vptr->rd_filled & 0xfffc, &regs->RBRDU);
247 @@ -1205,12 +1255,14 @@ static inline void velocity_give_many_rx
248  static int velocity_rx_refill(struct velocity_info *vptr)
249  {
250         int dirty = vptr->rd_dirty, done = 0, ret = 0;
251 +       HAIL("velocity_rx_refill");
252  
253         do {
254                 struct rx_desc *rd = vptr->rd_ring + dirty;
255  
256                 /* Fine for an all zero Rx desc at init time as well */
257 -               if (rd->rdesc0.owner == OWNED_BY_NIC)
258 +               /* if (rd->rdesc0.owner == OWNED_BY_NIC) BE */
259 +               if (rd->rdesc0 & cpu_to_le32(BE_OWNED_BY_NIC)) /* BE */
260                         break;
261  
262                 if (!vptr->rd_info[dirty].skb) {
263 @@ -1244,6 +1296,7 @@ static int velocity_init_rd_ring(struct 
264         int ret;
265         int mtu = vptr->dev->mtu;
266  
267 +       HAIL("velocity_init_rd_ring");
268         vptr->rx_buf_sz = (mtu <= ETH_DATA_LEN) ? PKT_BUF_SZ : mtu + 32;
269  
270         vptr->rd_info = kcalloc(vptr->options.numrx,
271 @@ -1275,6 +1328,7 @@ static void velocity_free_rd_ring(struct
272  {
273         int i;
274  
275 +       HAIL("velocity_free_rd_ring");
276         if (vptr->rd_info == NULL)
277                 return;
278  
279 @@ -1314,6 +1368,7 @@ static int velocity_init_td_ring(struct 
280         struct tx_desc *td;
281         struct velocity_td_info *td_info;
282  
283 +       HAIL("velocity_init_td_ring");
284         /* Init the TD ring entries */
285         for (j = 0; j < vptr->num_txq; j++) {
286                 curr = vptr->td_pool_dma[j];
287 @@ -1350,6 +1405,7 @@ static void velocity_free_td_ring_entry(
288         struct velocity_td_info * td_info = &(vptr->td_infos[q][n]);
289         int i;
290  
291 +       HAIL("velocity_free_td_ring_entry");
292         if (td_info == NULL)
293                 return;
294  
295 @@ -1379,6 +1435,7 @@ static void velocity_free_td_ring(struct
296  {
297         int i, j;
298  
299 +       HAIL("velocity_free_td_ring");
300         for (j = 0; j < vptr->num_txq; j++) {
301                 if (vptr->td_infos[j] == NULL)
302                         continue;
303 @@ -1406,34 +1463,42 @@ static int velocity_rx_srv(struct veloci
304         struct net_device_stats *stats = &vptr->stats;
305         int rd_curr = vptr->rd_curr;
306         int works = 0;
307 +       u16 wRSR; /* BE */
308  
309 +       HAILS("velocity_rx_srv", status);
310         do {
311                 struct rx_desc *rd = vptr->rd_ring + rd_curr;
312  
313                 if (!vptr->rd_info[rd_curr].skb)
314                         break;
315  
316 -               if (rd->rdesc0.owner == OWNED_BY_NIC)
317 +               /* if (rd->rdesc0.owner == OWNED_BY_NIC) BE */
318 +               if (rd->rdesc0 & cpu_to_le32(BE_OWNED_BY_NIC)) /* BE */
319                         break;
320  
321                 rmb();
322  
323 +               wRSR = (u16)(cpu_to_le32(rd->rdesc0)); /* BE */
324                 /*
325                  *      Don't drop CE or RL error frame although RXOK is off
326                  */
327 -               if ((rd->rdesc0.RSR & RSR_RXOK) || (!(rd->rdesc0.RSR & RSR_RXOK) && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) {
328 +               /* if ((rd->rdesc0.RSR & RSR_RXOK) || (!(rd->rdesc0.RSR & RSR_RXOK) && (rd->rdesc0.RSR & (RSR_CE | RSR_RL)))) { BE */
329 +               if ((wRSR & RSR_RXOK) || (!(wRSR & RSR_RXOK) && (wRSR & (RSR_CE | RSR_RL)))) { /* BE */
330                         if (velocity_receive_frame(vptr, rd_curr) < 0)
331                                 stats->rx_dropped++;
332                 } else {
333 -                       if (rd->rdesc0.RSR & RSR_CRC)
334 +                       /* if (rd->rdesc0.RSR & RSR_CRC) BE */
335 +                       if (wRSR & RSR_CRC) /* BE */
336                                 stats->rx_crc_errors++;
337 -                       if (rd->rdesc0.RSR & RSR_FAE)
338 +                       /* if (rd->rdesc0.RSR & RSR_FAE) BE */
339 +                       if (wRSR & RSR_FAE) /* BE */
340                                 stats->rx_frame_errors++;
341  
342                         stats->rx_dropped++;
343                 }
344  
345 -               rd->inten = 1;
346 +               /* rd->inten = 1; BE */
347 +               rd->ltwo |= cpu_to_le32(BE_INT_ENABLE); /* BE */
348  
349                 vptr->dev->last_rx = jiffies;
350  
351 @@ -1464,13 +1529,21 @@ static int velocity_rx_srv(struct veloci
352  
353  static inline void velocity_rx_csum(struct rx_desc *rd, struct sk_buff *skb)
354  {
355 +       u8 bCSM;
356 +       HAIL("velocity_rx_csum");
357         skb->ip_summed = CHECKSUM_NONE;
358  
359 -       if (rd->rdesc1.CSM & CSM_IPKT) {
360 -               if (rd->rdesc1.CSM & CSM_IPOK) {
361 -                       if ((rd->rdesc1.CSM & CSM_TCPKT) ||
362 -                                       (rd->rdesc1.CSM & CSM_UDPKT)) {
363 -                               if (!(rd->rdesc1.CSM & CSM_TUPOK)) {
364 +//     if (rd->rdesc1.CSM & CSM_IPKT) {
365 +//             if (rd->rdesc1.CSM & CSM_IPOK) {
366 +//                     if ((rd->rdesc1.CSM & CSM_TCPKT) ||
367 +//                                     (rd->rdesc1.CSM & CSM_UDPKT)) {
368 +//                             if (!(rd->rdesc1.CSM & CSM_TUPOK)) {
369 +       bCSM = (u8)(cpu_to_le32(rd->rdesc1) >> 16); /* BE */
370 +       if (bCSM & CSM_IPKT) {
371 +               if (bCSM & CSM_IPOK) {
372 +                       if ((bCSM & CSM_TCPKT) ||
373 +                           (bCSM & CSM_UDPKT)) {
374 +                               if (!(bCSM & CSM_TUPOK)) {      /* BE */
375                                         return;
376                                 }
377                         }
378 @@ -1496,9 +1569,11 @@ static inline int velocity_rx_copy(struc
379  {
380         int ret = -1;
381  
382 +       HAIL("velocity_rx_copy");
383         if (pkt_size < rx_copybreak) {
384                 struct sk_buff *new_skb;
385  
386 +               HAIL("velocity_rx_copy (working...)");
387                 new_skb = dev_alloc_skb(pkt_size + 2);
388                 if (new_skb) {
389                         new_skb->dev = vptr->dev;
390 @@ -1529,10 +1604,12 @@ static inline int velocity_rx_copy(struc
391  static inline void velocity_iph_realign(struct velocity_info *vptr,
392                                         struct sk_buff *skb, int pkt_size)
393  {
394 +       HAIL("velocity_iph_realign");
395         /* FIXME - memmove ? */
396         if (vptr->flags & VELOCITY_FLAGS_IP_ALIGN) {
397                 int i;
398  
399 +               HAIL("velocity_iph_realign (working...)");
400                 for (i = pkt_size; i >= 0; i--)
401                         *(skb->data + i + 2) = *(skb->data + i);
402                 skb_reserve(skb, 2);
403 @@ -1551,19 +1628,27 @@ static inline void velocity_iph_realign(
404  static int velocity_receive_frame(struct velocity_info *vptr, int idx)
405  {
406         void (*pci_action)(struct pci_dev *, dma_addr_t, size_t, int);
407 +       u16 pkt_len; /* BE */
408 +       u16 wRSR;    /* BE */
409 +       struct sk_buff *skb;
410         struct net_device_stats *stats = &vptr->stats;
411         struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]);
412         struct rx_desc *rd = &(vptr->rd_ring[idx]);
413 -       int pkt_len = rd->rdesc0.len;
414 -       struct sk_buff *skb;
415 +       /* int pkt_len = rd->rdesc0.len BE */;
416 +
417 +       pkt_len = ((cpu_to_le32(rd->rdesc0) >> 16) & 0x00003FFFUL); /* BE */
418 +       wRSR = (u16)(cpu_to_le32(rd->rdesc0)); /* BE */
419  
420 -       if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) {
421 +       HAIL("velocity_receive_frame");
422 +       /* if (rd->rdesc0.RSR & (RSR_STP | RSR_EDP)) { BE */
423 +       if (wRSR & (RSR_STP | RSR_EDP)) { /* BE */
424                 VELOCITY_PRT(MSG_LEVEL_VERBOSE, KERN_ERR " %s : the received frame span multple RDs.\n", vptr->dev->name);
425                 stats->rx_length_errors++;
426                 return -EINVAL;
427         }
428  
429 -       if (rd->rdesc0.RSR & RSR_MAR)
430 +       /* if (rd->rdesc0.RSR & RSR_MAR) BE */
431 +       if (wRSR & RSR_MAR) /* BE */
432                 vptr->stats.multicast++;
433  
434         skb = rd_info->skb;
435 @@ -1576,7 +1661,8 @@ static int velocity_receive_frame(struct
436          */
437  
438         if (vptr->flags & VELOCITY_FLAGS_VAL_PKT_LEN) {
439 -               if (rd->rdesc0.RSR & RSR_RL) {
440 +               /* if (rd->rdesc0.RSR & RSR_RL) { BE */
441 +               if (wRSR & RSR_RL) { /* BE */
442                         stats->rx_length_errors++;
443                         return -EINVAL;
444                 }
445 @@ -1620,6 +1706,7 @@ static int velocity_alloc_rx_buf(struct 
446         struct rx_desc *rd = &(vptr->rd_ring[idx]);
447         struct velocity_rd_info *rd_info = &(vptr->rd_info[idx]);
448  
449 +       HAIL("velocity_alloc_rx_buf");
450         rd_info->skb = dev_alloc_skb(vptr->rx_buf_sz + 64);
451         if (rd_info->skb == NULL)
452                 return -ENOMEM;
453 @@ -1637,10 +1724,14 @@ static int velocity_alloc_rx_buf(struct 
454          */
455  
456         *((u32 *) & (rd->rdesc0)) = 0;
457 -       rd->len = cpu_to_le32(vptr->rx_buf_sz);
458 -       rd->inten = 1;
459 +       /* rd->len = cpu_to_le32(vptr->rx_buf_sz);              BE */
460 +       /* rd->inten = 1;                                       BE */
461         rd->pa_low = cpu_to_le32(rd_info->skb_dma);
462 -       rd->pa_high = 0;
463 +       /* rd->pa_high = 0;                                     BE */
464 +       rd->ltwo &= cpu_to_le32(0xC000FFFFUL);                  /* BE */
465 +       rd->ltwo |= cpu_to_le32((vptr->rx_buf_sz << 16));       /* BE */
466 +       rd->ltwo |= cpu_to_le32(BE_INT_ENABLE);                 /* BE */
467 +       rd->ltwo &= cpu_to_le32(0xFFFF0000UL);                  /* BE */
468         return 0;
469  }
470  
471 @@ -1661,9 +1752,11 @@ static int velocity_tx_srv(struct veloci
472         int full = 0;
473         int idx;
474         int works = 0;
475 +       u16 wTSR; /* BE */
476         struct velocity_td_info *tdinfo;
477         struct net_device_stats *stats = &vptr->stats;
478  
479 +       HAILS("velocity_tx_srv", status);
480         for (qnum = 0; qnum < vptr->num_txq; qnum++) {
481                 for (idx = vptr->td_tail[qnum]; vptr->td_used[qnum] > 0;
482                         idx = (idx + 1) % vptr->options.numtx) {
483 @@ -1674,22 +1767,29 @@ static int velocity_tx_srv(struct veloci
484                         td = &(vptr->td_rings[qnum][idx]);
485                         tdinfo = &(vptr->td_infos[qnum][idx]);
486  
487 -                       if (td->tdesc0.owner == OWNED_BY_NIC)
488 +                       /* if (td->tdesc0.owner == OWNED_BY_NIC) BE */
489 +                       if (td->tdesc0 & cpu_to_le32(BE_OWNED_BY_NIC)) /* BE */
490                                 break;
491  
492                         if ((works++ > 15))
493                                 break;
494  
495 -                       if (td->tdesc0.TSR & TSR0_TERR) {
496 +                       wTSR = (u16)cpu_to_le32(td->tdesc0);
497 +                       /* if (td->tdesc0.TSR & TSR0_TERR) { BE */
498 +                       if (wTSR & TSR0_TERR) { /* BE */
499                                 stats->tx_errors++;
500                                 stats->tx_dropped++;
501 -                               if (td->tdesc0.TSR & TSR0_CDH)
502 +                               /* if (td->tdesc0.TSR & TSR0_CDH) BE */
503 +                               if (wTSR & TSR0_CDH) /* BE */
504                                         stats->tx_heartbeat_errors++;
505 -                               if (td->tdesc0.TSR & TSR0_CRS)
506 +                               /* if (td->tdesc0.TSR & TSR0_CRS) BE */
507 +                               if (wTSR & TSR0_CRS) /* BE */
508                                         stats->tx_carrier_errors++;
509 -                               if (td->tdesc0.TSR & TSR0_ABT)
510 +                               /* if (td->tdesc0.TSR & TSR0_ABT) BE */
511 +                               if (wTSR & TSR0_ABT) /* BE */
512                                         stats->tx_aborted_errors++;
513 -                               if (td->tdesc0.TSR & TSR0_OWC)
514 +                               /* if (td->tdesc0.TSR & TSR0_OWC) BE */
515 +                               if (wTSR & TSR0_OWC) /* BE */
516                                         stats->tx_window_errors++;
517                         } else {
518                                 stats->tx_packets++;
519 @@ -1778,6 +1878,7 @@ static void velocity_print_link_status(s
520  
521  static void velocity_error(struct velocity_info *vptr, int status)
522  {
523 +       HAILS("velocity_error", status);
524  
525         if (status & ISR_TXSTLI) {
526                 struct mac_regs __iomem * regs = vptr->mac_regs;
527 @@ -1867,6 +1968,7 @@ static void velocity_free_tx_buf(struct 
528         struct sk_buff *skb = tdinfo->skb;
529         int i;
530  
531 +       HAIL("velocity_free_tx_buf");
532         /*
533          *      Don't unmap the pre-allocated tx_bufs
534          */
535 @@ -2067,6 +2169,7 @@ static int velocity_xmit(struct sk_buff 
536         struct velocity_td_info *tdinfo;
537         unsigned long flags;
538         int index;
539 +       u32 lbufsz; /* BE */
540  
541         int pktlen = skb->len;
542  
543 @@ -2083,9 +2186,18 @@ static int velocity_xmit(struct sk_buff 
544         td_ptr = &(vptr->td_rings[qnum][index]);
545         tdinfo = &(vptr->td_infos[qnum][index]);
546  
547 -       td_ptr->tdesc1.TCPLS = TCPLS_NORMAL;
548 -       td_ptr->tdesc1.TCR = TCR0_TIC;
549 -       td_ptr->td_buf[0].queue = 0;
550 +       td_ptr->tdesc0 = 0x00000000UL;                            /* BE */
551 +       td_ptr->tdesc1 = 0x00000000UL;                            /* BE */
552 +
553 +       /* td_ptr->tdesc1.TCPLS = TCPLS_NORMAL;         BE */
554 +       td_ptr->tdesc1 &= cpu_to_le32(0xfcffffffUL);              /* BE */
555 +       td_ptr->tdesc1 |= cpu_to_le32(((u32)TCPLS_NORMAL) << 24); /* BE */
556 +
557 +       /* td_ptr->tdesc1.TCR = TCR0_TIC;               BE */
558 +       td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_TIC);                /* BE */
559 +
560 +       /*      td_ptr->td_buf[0].queue = 0;            BE */
561 +       td_ptr->td_buf[0].ltwo &= cpu_to_le32(~BE_QUEUE_ENABLE);  /* BE */
562  
563         /*
564          *      Pad short frames.
565 @@ -2097,20 +2209,36 @@ static int velocity_xmit(struct sk_buff 
566                 memset(tdinfo->buf + skb->len, 0, ETH_ZLEN - skb->len);
567                 tdinfo->skb = skb;
568                 tdinfo->skb_dma[0] = tdinfo->buf_dma;
569 -               td_ptr->tdesc0.pktsize = pktlen;
570 +               /* td_ptr->tdesc0.pktsize = pktlen; */
571 +               td_ptr->tdesc0 &= cpu_to_le32(0xc000ffffUL); /* BE */
572 +               lbufsz = pktlen; /* Assign, and make sure it's unsigned 32 bits - BE */
573 +               lbufsz = lbufsz << 16; /* BE - shift over     */
574 +               td_ptr->tdesc0 |= cpu_to_le32(lbufsz); /* BE */
575 +
576                 td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
577 -               td_ptr->td_buf[0].pa_high = 0;
578 -               td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
579 +               /* td_ptr->td_buf[0].pa_high = 0; */
580 +               /* td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize; */
581 +               td_ptr->td_buf[0].ltwo = cpu_to_le32(lbufsz);   /* BE */
582                 tdinfo->nskb_dma = 1;
583 -               td_ptr->tdesc1.CMDZ = 2;
584 +               /* td_ptr->tdesc1.CMDZ = 2; */
585 +               td_ptr->tdesc1 &= cpu_to_le32(0x0fffffffUL); /* BE */
586 +               td_ptr->tdesc1 |= cpu_to_le32(((u32)0x2) << 28); /* BE */
587         } else
588  #ifdef VELOCITY_ZERO_COPY_SUPPORT
589 +       /*
590 +        * BE - NOTE on the VELOCITY_ZERO_COPY_SUPPORT:
591 +        * This block of code has NOT been patched up for BE support, as
592 +        * it is certainly broken -- if it compiles at all.  Since the BE
593 +        * fixes depend on the broken code, attempts to convert to BE support
594 +        * would almost certainly confuse more than help.
595 +        */
596         if (skb_shinfo(skb)->nr_frags > 0) {
597                 int nfrags = skb_shinfo(skb)->nr_frags;
598                 tdinfo->skb = skb;
599                 if (nfrags > 6) {
600                         skb_copy_from_linear_data(skb, tdinfo->buf, skb->len);
601                         tdinfo->skb_dma[0] = tdinfo->buf_dma;
602 +                       /* BE: Er, exactly what value are we assigning in this next line? */
603                         td_ptr->tdesc0.pktsize =
604                         td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
605                         td_ptr->td_buf[0].pa_high = 0;
606 @@ -2127,6 +2255,7 @@ static int velocity_xmit(struct sk_buff 
607                         /* FIXME: support 48bit DMA later */
608                         td_ptr->td_buf[i].pa_low = cpu_to_le32(tdinfo->skb_dma);
609                         td_ptr->td_buf[i].pa_high = 0;
610 +                       /* BE: This next line can't be right: */
611                         td_ptr->td_buf[i].bufsize = skb->len->skb->data_len;
612  
613                         for (i = 0; i < nfrags; i++) {
614 @@ -2144,7 +2273,7 @@ static int velocity_xmit(struct sk_buff 
615                 }
616  
617         } else
618 -#endif
619 +#endif /* (broken) VELOCITY_ZERO_COPY_SUPPORT */
620         {
621                 /*
622                  *      Map the linear network buffer into PCI space and
623 @@ -2152,19 +2281,29 @@ static int velocity_xmit(struct sk_buff 
624                  */
625                 tdinfo->skb = skb;
626                 tdinfo->skb_dma[0] = pci_map_single(vptr->pdev, skb->data, pktlen, PCI_DMA_TODEVICE);
627 -               td_ptr->tdesc0.pktsize = pktlen;
628 +               /* td_ptr->tdesc0.pktsize = pktlen;                               BE */
629 +               td_ptr->tdesc0 &= cpu_to_le32(0xc000ffffUL);                   /* BE */
630 +               lbufsz = pktlen; /* Assign, and make sure it's unsigned 32 bits - BE */
631 +               lbufsz = lbufsz << 16;                                         /* BE */
632 +               td_ptr->tdesc0 |= cpu_to_le32(lbufsz);                         /* BE */
633                 td_ptr->td_buf[0].pa_low = cpu_to_le32(tdinfo->skb_dma[0]);
634 -               td_ptr->td_buf[0].pa_high = 0;
635 -               td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;
636 +               /* td_ptr->td_buf[0].pa_high = 0;                                 BE */
637 +               /* td_ptr->td_buf[0].bufsize = td_ptr->tdesc0.pktsize;            BE */
638 +               td_ptr->td_buf[0].ltwo = cpu_to_le32(lbufsz);                  /* BE */
639                 tdinfo->nskb_dma = 1;
640 -               td_ptr->tdesc1.CMDZ = 2;
641 +               /* td_ptr->tdesc1.CMDZ = 2;                                       BE */
642 +               td_ptr->tdesc1 &= cpu_to_le32(0x0fffffffUL);                   /* BE */
643 +               td_ptr->tdesc1 |= cpu_to_le32(((u32)0x2) << 28);               /* BE */
644         }
645  
646         if (vptr->vlgrp && vlan_tx_tag_present(skb)) {
647 -               td_ptr->tdesc1.pqinf.VID = vlan_tx_tag_get(skb);
648 -               td_ptr->tdesc1.pqinf.priority = 0;
649 -               td_ptr->tdesc1.pqinf.CFI = 0;
650 -               td_ptr->tdesc1.TCR |= TCR0_VETAG;
651 +               /* td_ptr->tdesc1.pqinf.VID = vlan_tx_tag_get(skb);               BE */
652 +               /* td_ptr->tdesc1.pqinf.priority = 0;                             BE */
653 +               /* td_ptr->tdesc1.pqinf.CFI = 0;                                  BE */
654 +               /* td_ptr->tdesc1.TCR |= TCR0_VETAG;                              BE */
655 +               td_ptr->tdesc1 &= cpu_to_le32(0xFFFF0000UL);                   /* BE */
656 +               td_ptr->tdesc1 |= cpu_to_le32(vlan_tx_tag_get(skb));           /* BE */
657 +               td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_VETAG);                   /* BE */
658         }
659  
660         /*
661 @@ -2174,26 +2313,34 @@ static int velocity_xmit(struct sk_buff 
662                                  && (skb->ip_summed == CHECKSUM_PARTIAL)) {
663                 const struct iphdr *ip = ip_hdr(skb);
664                 if (ip->protocol == IPPROTO_TCP)
665 -                       td_ptr->tdesc1.TCR |= TCR0_TCPCK;
666 +                       /* td_ptr->tdesc1.TCR |= TCR0_TCPCK;    BE */
667 +                       td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_TCPCK);    /* BE */
668                 else if (ip->protocol == IPPROTO_UDP)
669 -                       td_ptr->tdesc1.TCR |= (TCR0_UDPCK);
670 -               td_ptr->tdesc1.TCR |= TCR0_IPCK;
671 -       }
672 +                       /* td_ptr->tdesc1.TCR |= (TCR0_UDPCK);  BE */
673 +                       td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_UDPCK);    /* BE */
674 +               /* td_ptr->tdesc1.TCR |= TCR0_IPCK;             BE */
675 +               td_ptr->tdesc1 |= cpu_to_le32(BE_TCR_IPCK);             /* BE */
676 +       }
677         {
678  
679                 int prev = index - 1;
680  
681                 if (prev < 0)
682                         prev = vptr->options.numtx - 1;
683 -               td_ptr->tdesc0.owner = OWNED_BY_NIC;
684 +               /* td_ptr->tdesc0.owner = OWNED_BY_NIC; BE */
685 +               td_ptr->tdesc0 |= cpu_to_le32(BE_OWNED_BY_NIC); /* BE */
686                 vptr->td_used[qnum]++;
687                 vptr->td_curr[qnum] = (index + 1) % vptr->options.numtx;
688  
689                 if (AVAIL_TD(vptr, qnum) < 1)
690                         netif_stop_queue(dev);
691  
692 -               td_ptr = &(vptr->td_rings[qnum][prev]);
693 -               td_ptr->td_buf[0].queue = 1;
694 +               td_ptr = &(vptr->td_rings[qnum][prev]);
695 +               /* td_ptr->td_buf[0].queue = 1; BE */
696 +               td_ptr->td_buf[0].ltwo |= cpu_to_le32(BE_QUEUE_ENABLE); /* BE */
697 +               if (vdebug&2) printk(KERN_NOTICE "velocity_xmit: (%s) len=%d idx=%d tdesc0=0x%x tdesc1=0x%x ltwo=0x%x\n",
698 +                       (pktlen<ETH_ZLEN) ? "short" : "normal", pktlen, index,
699 +                       td_ptr->tdesc0, td_ptr->tdesc1, td_ptr->td_buf[0].ltwo);
700                 mac_tx_queue_wake(vptr->mac_regs, qnum);
701         }
702         dev->trans_start = jiffies;
703 @@ -2219,7 +2366,7 @@ static int velocity_intr(int irq, void *
704         u32 isr_status;
705         int max_count = 0;
706  
707 -
708 +       HAIL("velocity_intr");
709         spin_lock(&vptr->lock);
710         isr_status = mac_read_isr(vptr->mac_regs);
711  
712 @@ -2238,7 +2385,10 @@ static int velocity_intr(int irq, void *
713  
714         while (isr_status != 0) {
715                 mac_write_isr(vptr->mac_regs, isr_status);
716 -               if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI)))
717 +               HAILS("velocity_intr",isr_status);
718 +               /* MJW - velocity_error is ALWAYS called; need to mask off some other flags */
719 +               /* if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI))) */
720 +               if (isr_status & (~(ISR_PRXI | ISR_PPRXI | ISR_PTXI | ISR_PPTXI | ISR_PTX0I | ISR_ISR0)))
721                         velocity_error(vptr, isr_status);
722                 if (isr_status & (ISR_PRXI | ISR_PPRXI))
723                         max_count += velocity_rx_srv(vptr, isr_status);
724 @@ -2276,6 +2426,7 @@ static void velocity_set_multi(struct ne
725         int i;
726         struct dev_mc_list *mclist;
727  
728 +       HAIL("velocity_set_multi");
729         if (dev->flags & IFF_PROMISC) { /* Set promiscuous. */
730                 writel(0xffffffff, &regs->MARCAM[0]);
731                 writel(0xffffffff, &regs->MARCAM[4]);
732 @@ -2319,6 +2470,7 @@ static struct net_device_stats *velocity
733  {
734         struct velocity_info *vptr = netdev_priv(dev);
735  
736 +       HAIL("net_device_stats");
737         /* If the hardware is down, don't touch MII */
738         if(!netif_running(dev))
739                 return &vptr->stats;
740 @@ -2363,6 +2515,7 @@ static int velocity_ioctl(struct net_dev
741         struct velocity_info *vptr = netdev_priv(dev);
742         int ret;
743  
744 +       HAIL("velocity_ioctl");
745         /* If we are asked for information and the device is power
746            saving then we need to bring the device back up to talk to it */
747  
748 @@ -2581,6 +2734,8 @@ static int velocity_mii_read(struct mac_
749  {
750         u16 ww;
751  
752 +       HAIL("velocity_mii_read");
753 +       HAIL("velocity_mii_write");
754         /*
755          *      Disable MIICR_MAUTO, so that mii addr can be set normally
756          */
757 Index: linux-2.6.24.7/drivers/net/via-velocity.h
758 ===================================================================
759 --- linux-2.6.24.7.orig/drivers/net/via-velocity.h
760 +++ linux-2.6.24.7/drivers/net/via-velocity.h
761 @@ -196,64 +196,70 @@
762   *     Receive descriptor
763   */
764  
765 -struct rdesc0 {
766 -       u16 RSR;                /* Receive status */
767 -       u16 len:14;             /* Received packet length */
768 -       u16 reserved:1;
769 -       u16 owner:1;            /* Who owns this buffer ? */
770 -};
771 -
772 -struct rdesc1 {
773 -       u16 PQTAG;
774 -       u8 CSM;
775 -       u8 IPKT;
776 -};
777 +//struct rdesc0 {
778 +//     u16 RSR;                /* Receive status */
779 +//     u16 len:14;             /* Received packet length */
780 +//     u16 reserved:1;
781 +//     u16 owner:1;            /* Who owns this buffer ? */
782 +//};
783 +
784 +//struct rdesc1 {
785 +//     u16 PQTAG;
786 +//     u8 CSM;
787 +//     u8 IPKT;
788 +//};
789  
790  struct rx_desc {
791 -       struct rdesc0 rdesc0;
792 -       struct rdesc1 rdesc1;
793 +//     struct rdesc0 rdesc0;
794 +//     struct rdesc1 rdesc1;
795 +       u32 rdesc0;
796 +       u32 rdesc1;
797         u32 pa_low;             /* Low 32 bit PCI address */
798 -       u16 pa_high;            /* Next 16 bit PCI address (48 total) */
799 -       u16 len:15;             /* Frame size */
800 -       u16 inten:1;            /* Enable interrupt */
801 +//     u16 pa_high;            /* Next 16 bit PCI address (48 total) */
802 +//     u16 len:15;             /* Frame size */
803 +//     u16 inten:1;            /* Enable interrupt */
804 +       u32 ltwo;
805  } __attribute__ ((__packed__));
806  
807  /*
808   *     Transmit descriptor
809   */
810  
811 -struct tdesc0 {
812 -       u16 TSR;                /* Transmit status register */
813 -       u16 pktsize:14;         /* Size of frame */
814 -       u16 reserved:1;
815 -       u16 owner:1;            /* Who owns the buffer */
816 -};
817 -
818 -struct pqinf {                 /* Priority queue info */
819 -       u16 VID:12;
820 -       u16 CFI:1;
821 -       u16 priority:3;
822 -} __attribute__ ((__packed__));
823 -
824 -struct tdesc1 {
825 -       struct pqinf pqinf;
826 -       u8 TCR;
827 -       u8 TCPLS:2;
828 -       u8 reserved:2;
829 -       u8 CMDZ:4;
830 -} __attribute__ ((__packed__));
831 +//struct tdesc0 {
832 +//     u16 TSR;                /* Transmit status register */
833 +//     u16 pktsize:14;         /* Size of frame */
834 +//     u16 reserved:1;
835 +//     u16 owner:1;            /* Who owns the buffer */
836 +//};
837 +
838 +//struct pqinf {                       /* Priority queue info */
839 +//     u16 VID:12;
840 +//     u16 CFI:1;
841 +//     u16 priority:3;
842 +//} __attribute__ ((__packed__));
843 +
844 +//struct tdesc1 {
845 +//     struct pqinf pqinf;
846 +//     u8 TCR;
847 +//     u8 TCPLS:2;
848 +//     u8 reserved:2;
849 +//     u8 CMDZ:4;
850 +//} __attribute__ ((__packed__));
851  
852  struct td_buf {
853         u32 pa_low;
854 -       u16 pa_high;
855 -       u16 bufsize:14;
856 -       u16 reserved:1;
857 -       u16 queue:1;
858 +//     u16 pa_high;
859 +//     u16 bufsize:14;
860 +//     u16 reserved:1;
861 +//     u16 queue:1;
862 +       u32 ltwo;
863  } __attribute__ ((__packed__));
864  
865  struct tx_desc {
866 -       struct tdesc0 tdesc0;
867 -       struct tdesc1 tdesc1;
868 +//     struct tdesc0 tdesc0;
869 +//     struct tdesc1 tdesc1;
870 +       u32 tdesc0;
871 +       u32 tdesc1;
872         struct td_buf td_buf[7];
873  };
874  
875 @@ -279,6 +285,16 @@ enum  velocity_owner {
876         OWNED_BY_NIC = 1
877  };
878  
879 +/* Constants added for the BE fixes */
880 +#define BE_OWNED_BY_NIC    0x80000000UL
881 +#define BE_INT_ENABLE      0x80000000UL
882 +#define BE_QUEUE_ENABLE    0x80000000UL
883 +#define BE_TCR_TIC         0x00800000UL
884 +#define BE_TCR_VETAG       0x00200000UL
885 +#define BE_TCR_TCPCK       0x00040000UL
886 +#define BE_TCR_UDPCK       0x00080000UL
887 +#define BE_TCR_IPCK        0x00100000UL
888 +
889  
890  /*
891   *     MAC registers and macros.
892 @@ -1512,6 +1528,7 @@ enum velocity_flow_cntl_type {
893  };
894  
895  struct velocity_opt {
896 +       int velo_debug;                 /* debug flag */
897         int numrx;                      /* Number of RX descriptors */
898         int numtx;                      /* Number of TX descriptors */
899         enum speed_opt spd_dpx;         /* Media link mode */