On Fri, Jun 4, 2010 at 4:31 PM, Bob Copeland <m...@bobcopeland.com> wrote:
> On Fri, Jun 4, 2010 at 4:24 PM, Robert Brown <robert.br...@gmail.com> > wrote: > > > > Here's another instance of data corruption. One block containing labels > > 110413 & 110414 is duplicated in the output file. > > I've instrumented ath5k_tasklet_rx to print "ATH" followed by packet > block > > information. > > Can you post the printks you added? Just so I can understand what exactly > the data is. Here is a diff of ath5k/base.c and mac80211.c showing where I added print statements. bob ==================== *** drivers/net/wireless/ath/ath5k/base.c.~1~ Tue May 18 15:06:03 2010 --- drivers/net/wireless/ath/ath5k/base.c Fri Jun 4 14:10:47 2010 *************** *** 1924,1929 **** --- 1924,1982 ---- return 0; } + static void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) + { + size_t i; + char const *hs = haystack; + + if (needlelen == 0) + return (void *)haystack; + + if (needlelen > haystacklen || haystack == NULL || needle == NULL) + return NULL; + + for (i = 0; i <= haystacklen - needlelen; i++) { + if (memcmp(hs + i, needle, needlelen) == 0) + return (void *)(hs + i); + } + + return NULL; + } + + static int block_number(char *data, int length, int *block_number, int *offset) { + char *foobar; + char *xx = memmem(data, length, "XXXXXXXXXXXXXXXXXXXX ", 21); + + if (!xx) + return 0; + + if (xx + 28 > data + length) + return 0; + + *block_number = simple_strtoul(xx + 21, &foobar, 10); + *offset = xx - data + 21; + return 1; + } + + static void print_block(char *prefix, int place, struct sk_buff *skb) { + int block_number_1 = 0; + int block_number_2 = 0; + int offset; + + if (block_number(skb->data, skb->len, &block_number_1, &offset)) { + block_number(skb->data + offset, skb->len - offset, &block_number_2, &offset); + } + printk(KERN_DEBUG "%s %d block %d %d\n", prefix, place, block_number_1, block_number_2); + if (skb->next) { + skb = skb->next; + if (block_number(skb->data, skb->len, &block_number_1, &offset)) { + block_number(skb->data + offset, skb->len - offset, &block_number_2, &offset); + } + printk(KERN_DEBUG "%snext %d block %d %d\n", prefix, place, block_number_1, block_number_2); + } + } + + static void ath5k_tasklet_rx(unsigned long data) { *************** *** 2081,2087 **** sc->curband->bitrates[rxs->rate_idx].hw_value_short) rxs->flag |= RX_FLAG_SHORTPRE; ! ath5k_debug_dump_skb(sc, skb, "RX ", 0); ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi); --- 2134,2153 ---- sc->curband->bitrates[rxs->rate_idx].hw_value_short) rxs->flag |= RX_FLAG_SHORTPRE; ! ! #define OFFSET 1000 ! if (skb->len > OFFSET + HIST_SIZE) { ! unsigned char *data = skb->data + OFFSET; ! if (memcmp(sc->history, data, HIST_SIZE) == 0) { ! ath5k_debug_dump_skb(sc, skb, "ZZ ", 0); ! } ! memcpy(sc->history, data, HIST_SIZE); ! } ! ! ! ! ! // ath5k_debug_dump_skb(sc, skb, "RX ", 0); ath5k_update_beacon_rssi(sc, skb, rs.rs_rssi); *************** *** 2089,2094 **** --- 2155,2165 ---- if (sc->opmode == NL80211_IFTYPE_ADHOC) ath5k_check_ibss_tsf(sc, skb, rxs); + + print_block("ATH", 0, skb); /* XXXXXXXXXXXXXXXXXXXX */ + + + ieee80211_rx(sc->hw, skb); bf->skb = next_skb; *************** *** 2334,2339 **** --- 2405,2411 ---- ATH5K_DBG(sc, ATH5K_DEBUG_BEACON, "stuck beacon time (%u missed)\n", sc->bmisscount); + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "beacon, resetting\n"); tasklet_schedule(&sc->restq); } return; *************** *** 2741,2746 **** --- 2813,2819 ---- * Fatal errors are unrecoverable. * Typically these are caused by DMA errors. */ + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "INT_FATAL, resetting\n"); tasklet_schedule(&sc->restq); } else if (unlikely(status & AR5K_INT_RXORN)) { /* *************** *** 2753,2761 **** * this guess is copied from the HAL. */ sc->stats.rxorn_intr++; ! if (ah->ah_mac_srev < AR5K_SREV_AR5212) tasklet_schedule(&sc->restq); ! else tasklet_schedule(&sc->rxtq); } else { if (status & AR5K_INT_SWBA) { --- 2826,2835 ---- * this guess is copied from the HAL. */ sc->stats.rxorn_intr++; ! if (ah->ah_mac_srev < AR5K_SREV_AR5212) { ! ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "RXORN, resetting\n"); tasklet_schedule(&sc->restq); ! } else tasklet_schedule(&sc->rxtq); } else { if (status & AR5K_INT_SWBA) { *************** *** 2986,2991 **** --- 3060,3066 ---- { int ret; + ATH5K_DBG(sc, ATH5K_DEBUG_RESET, "wake, resetting\n"); ret = ath5k_reset(sc, sc->curchan); if (!ret) ieee80211_wake_queues(sc->hw); *** net/mac80211/rx.c.~1~ Tue May 18 15:06:03 2010 --- net/mac80211/rx.c Fri Jun 4 14:11:05 2010 *************** *** 1227,1232 **** --- 1227,1300 ---- return NULL; } + #if 0 + static int bad_block(struct sk_buff *skb) { + int block_number_1, block_number_2; + int offset; + + if (block_number(skb->data, skb->len, &block_number_1, &offset) + && block_number(skb->data + offset, skb->len - offset, &block_number_2, &offset) + && block_number_2 <= block_number_1) + return block_number_1; + + return 0; + } + #endif + + + static void *memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen) + { + size_t i; + char const *hs = haystack; + + if (needlelen == 0) + return (void *)haystack; + + if (needlelen > haystacklen || haystack == NULL || needle == NULL) + return NULL; + + for (i = 0; i <= haystacklen - needlelen; i++) { + if (memcmp(hs + i, needle, needlelen) == 0) + return (void *)(hs + i); + } + + return NULL; + } + + static int block_number(char *data, int length, int *block_number, int *offset) { + char *foobar; + char *xx = memmem(data, length, "XXXXXXXXXXXXXXXXXXXX ", 21); + + if (!xx) + return 0; + + if (xx + 28 > data + length) + return 0; + + *block_number = simple_strtoul(xx + 21, &foobar, 10); + *offset = xx - data + 21; + return 1; + } + + static void print_block(char *prefix, int place, struct sk_buff *skb) { + int block_number_1 = 0; + int block_number_2 = 0; + int offset; + + if (block_number(skb->data, skb->len, &block_number_1, &offset)) { + block_number(skb->data + offset, skb->len - offset, &block_number_2, &offset); + } + printk(KERN_DEBUG "%s %d block %d %d\n", prefix, place, block_number_1, block_number_2); + if (skb->next) { + skb = skb->next; + if (block_number(skb->data, skb->len, &block_number_1, &offset)) { + block_number(skb->data + offset, skb->len - offset, &block_number_2, &offset); + } + printk(KERN_DEBUG "%snext %d block %d %d\n", prefix, place, block_number_1, block_number_2); + } + } + + static ieee80211_rx_result debug_noinline ieee80211_rx_h_defragment(struct ieee80211_rx_data *rx) { *************** *** 1329,1334 **** --- 1397,1406 ---- dev_kfree_skb(skb); } + + print_block("FRAG", 0, rx->skb); /* XXXXXXXXXXXXXXXXXXXX */ + + /* Complete frame has been reassembled - process it now */ rx->flags |= IEEE80211_RX_FRAGMENTED; *************** *** 1499,1504 **** --- 1571,1577 ---- return true; } + /* * requires that rx->skb is a frame with ethernet header */ *************** *** 1573,1578 **** --- 1646,1654 ---- /* deliver to local stack */ skb->protocol = eth_type_trans(skb, dev); memset(skb->cb, 0, sizeof(skb->cb)); + + print_block("MACO", 0, skb); /* XXXXXXXXXXXXXXXXXXXX */ + netif_rx(skb); } } *************** *** 2127,2132 **** --- 2203,2209 ---- GFP_ATOMIC); } + /* TODO: use IEEE80211_RX_FRAGMENTED */ static void ieee80211_rx_cooked_monitor(struct ieee80211_rx_data *rx, struct ieee80211_rate *rate) *************** *** 2188,2193 **** --- 2265,2274 ---- if (prev_dev) { skb2 = skb_clone(skb, GFP_ATOMIC); if (skb2) { + /* int block = bad_block(skb2); */ + /* if (block) */ + /* printk(KERN_DEBUG "ZZ1 bad block %d\n", block); */ + /* print_block(1, skb2); */ skb2->dev = prev_dev; netif_rx(skb2); } *************** *** 2199,2204 **** --- 2280,2290 ---- } if (prev_dev) { + /* int block = bad_block(skb); */ + /* if (block) */ + /* printk(KERN_DEBUG "ZZ2 bad block %d\n", block); */ + /* print_block(2, skb); */ + skb->dev = prev_dev; netif_rx(skb); skb = NULL; *************** *** 2430,2435 **** --- 2516,2523 ---- return; } + print_block("MACI", 0, skb); /* XXXXXXXXXXXXXXXXXXXX */ + hdr = (struct ieee80211_hdr *)skb->data; ieee80211_parse_qos(&rx); ieee80211_verify_alignment(&rx);
_______________________________________________ ath5k-devel mailing list ath5k-devel@lists.ath5k.org https://lists.ath5k.org/mailman/listinfo/ath5k-devel