static inline int cpsw_ale_get_field(u32 *ale_entry, u32 start, u32 bits)
 {
-       int idx;
+       int idx, idx2;
+       u32 hi_val = 0;
 
        idx    = start / 32;
+       idx2 = (start + bits - 1) / 32;
+       /* Check if bits to be fetched exceed a word */
+       if (idx != idx2) {
+               idx2 = 2 - idx2; /* flip */
+               hi_val = ale_entry[idx2] << ((idx2 * 32) - start);
+       }
        start -= idx * 32;
        idx    = 2 - idx; /* flip */
-       return (ale_entry[idx] >> start) & BITMASK(bits);
+       return (hi_val + (ale_entry[idx] >> start)) & BITMASK(bits);
 }
 
 static inline void cpsw_ale_set_field(u32 *ale_entry, u32 start, u32 bits,
                                      u32 value)
 {
-       int idx;
+       int idx, idx2;
 
        value &= BITMASK(bits);
-       idx    = start / 32;
+       idx = start / 32;
+       idx2 = (start + bits - 1) / 32;
+       /* Check if bits to be set exceed a word */
+       if (idx != idx2) {
+               idx2 = 2 - idx2; /* flip */
+               ale_entry[idx2] &= ~(BITMASK(bits + start - (idx2 * 32)));
+               ale_entry[idx2] |= (value >> ((idx2 * 32) - start));
+       }
        start -= idx * 32;
-       idx    = 2 - idx; /* flip */
+       idx = 2 - idx; /* flip */
        ale_entry[idx] &= ~(BITMASK(bits) << start);
        ale_entry[idx] |=  (value << start);
 }