static void do_rx(unsigned long mac_ptr) { struct zd_mac *mac = (struct zd_mac *)mac_ptr; struct sk_buff *skb; while ((skb = skb_dequeue(&mac->rx_queue)) != NULL) zd_mac_rx(mac, skb); }
static void handle_rx_packet(struct zd_usb *usb, const u8 *buffer, unsigned int length) { int i; const struct rx_length_info *length_info; if (length < sizeof(struct rx_length_info)) { /* It's not a complete packet anyhow. */ printk("%s: invalid, small RX packet : %d\n", __func__, length); return; } length_info = (struct rx_length_info *) (buffer + length - sizeof(struct rx_length_info)); /* It might be that three frames are merged into a single URB * transaction. We have to check for the length info tag. * * While testing we discovered that length_info might be unaligned, * because if USB transactions are merged, the last packet will not * be padded. Unaligned access might also happen if the length_info * structure is not present. */ if (get_unaligned_le16(&length_info->tag) == RX_LENGTH_INFO_TAG) { unsigned int l, k, n; for (i = 0, l = 0;; i++) { k = get_unaligned_le16(&length_info->length[i]); if (k == 0) return; n = l+k; if (n > length) return; zd_mac_rx(zd_usb_to_hw(usb), buffer+l, k); if (i >= 2) return; l = (n+3) & ~3; } } else { zd_mac_rx(zd_usb_to_hw(usb), buffer, length); } }