len = le16_to_cpu(*(u16 *) (head->data));
        DMA_TRACE(("%s: dma_rx len %d\n", di->name, len));
-
-#if defined(__mips__)
-#define OSL_UNCACHED(va)        ((void *)KSEG1ADDR((va)))
-       if (!len) {
-               while (!(len = *(u16 *) OSL_UNCACHED(head->data)))
-                       udelay(1);
-
-               *(u16 *) (head->data) = cpu_to_le16((u16) len);
-       }
-#endif                         /* defined(__mips__) */
+       dma_spin_for_len(len, head);
 
        /* set actual length */
        pkt_len = min((di->rxoffset + len), di->rxbufsize);
 
 extern uint dma_addrwidth(si_t *sih, void *dmaregs);
 void dma_walk_packets(struct hnddma_pub *dmah, void (*callback_fnc)
                      (void *pkt, void *arg_a), void *arg_a);
+
+/*
+ * DMA(Bug) on some chips seems to declare that the packet is ready, but the
+ * packet length is not updated yet (by DMA) on the expected time.
+ * Workaround is to hold processor till DMA updates the length, and stay off
+ * the bus to allow DMA update the length in buffer
+ */
+static inline void dma_spin_for_len(uint len, struct sk_buff *head)
+{
+#if defined(__mips__)
+       if (!len) {
+               while (!(len = *(u16 *) KSEG1ADDR(head->data)))
+                       udelay(1);
+
+               *(u16 *) (head->data) = cpu_to_le16((u16) len);
+       }
+#endif                         /* defined(__mips__) */
+}
+
 #endif                         /* _hnddma_h_ */