static void adapter_sdio_rx_packet(struct net_adapter *adapter, int len) { struct hw_packet_header *hdr; int rlen; u32 type; u8 *ofs; struct sk_buff *rx_skb; rlen = len; ofs = (u8 *)adapter->hw.receive_buffer; while (rlen > 0) { hdr = (struct hw_packet_header *)ofs; type = HWPKTTYPENONE; /* "WD", "WC", "WP" or "WE" */ if (unlikely(hdr->id0 != 'W')) { if (rlen > 4) { pr_debug("Wrong packet \ ID (%02x %02x)", hdr->id0, hdr->id1); } /* skip rest of packets */ break; } /* check packet type */ switch (hdr->id1) { case 'P': { u32 l = 0; type = HWPKTTYPEPRIVATE; /* process packet */ l = process_private_cmd(adapter, ofs); /* shift */ ofs += l; rlen -= l; /* process next packet */ continue; } case 'C': type = HWPKTTYPECONTROL; break; case 'D': type = HWPKTTYPEDATA; break; case 'E': /* skip rest of buffer */ break; default: pr_debug("hwParseReceivedData : \ Wrong packet ID [%02x %02x]", hdr->id0, hdr->id1); /* skip rest of buffer */ break; } if (type == HWPKTTYPENONE) break; if (likely(!adapter->downloading)) { if (unlikely(hdr->length > WIMAX_MAX_TOTAL_SIZE || ((hdr->length + sizeof(struct hw_packet_header)) > rlen))) { pr_debug("Packet length is \ too big (%d)", hdr->length); /* skip rest of packets */ break; } }
static void adapter_rx_packet(struct net_adapter *adapter, struct buffer_descriptor *bufdsc) { struct hw_packet_header *hdr; s32 rlen = bufdsc->length; u32 l; u8 *ofs; struct sk_buff *rx_skb; ofs = (u8 *)bufdsc->buffer; while (rlen > 0) { hdr = (struct hw_packet_header *)ofs; /* "WD", "WC", "WP" or "WE" */ if (unlikely(hdr->id0 != 'W')) { /*Ignore if it is the 4 byte allignment*/ pr_warn("Wrong packet \ ID (%02x %02x) rlen = %d\n", hdr->id0, hdr->id1, rlen); /* skip rest of packets */ break; } /* change offset */ ofs += sizeof(*hdr); rlen -= sizeof(*hdr); /* check packet type */ switch (hdr->id1) { case 'P': { /* revert offset */ ofs -= sizeof(*hdr); rlen += sizeof(*hdr); /* process packet */ l = process_private_cmd(adapter, ofs); /* shift */ ofs += l; rlen -= l; /* process next packet */ continue; } case 'C': if (!adapter->downloading) { ofs += 2; rlen -= 2; control_recv(adapter, (u8 *)ofs, hdr->length); break; } else { hdr->length -= sizeof(*hdr); process_indicate_packet(adapter, ofs); break; } case 'D': ofs += 2; rlen -= 2; if (hdr->length > BUFFER_DATA_SIZE) { pr_warn("Data packet too large"); adapter->netstats.rx_dropped++; break; } if (likely(hdr->length <= (WIMAX_MTU_SIZE + 2))) { rx_skb = cmc7xx_fetch_skb(adapter); if (!rx_skb) { pr_err("unable to allocate skb"); break; } } else { rx_skb = dev_alloc_skb(hdr->length + (ETHERNET_ADDRESS_LENGTH * 2) + NET_IP_ALIGN); if (!rx_skb) { pr_err("unable to allocate skb"); break; } cmc7xx_prepare_skb(adapter, rx_skb); } memcpy(skb_put(rx_skb, hdr->length), (u8 *)ofs, hdr->length); rx_skb->protocol = eth_type_trans(rx_skb, adapter->net); if (netif_rx_ni(rx_skb) == NET_RX_DROP) { pr_debug("packet dropped!"); adapter->netstats.rx_dropped++; } adapter->netstats.rx_packets++; adapter->netstats.rx_bytes += (hdr->length + (ETHERNET_ADDRESS_LENGTH * 2)); break; case 'E': pr_warn("%s :Wrong packet Extended ID [%02x %02x]", __func__, hdr->id0, hdr->id1); /* skip rest of buffer */ goto out; default: pr_warn("%s :Wrong packet ID [%02x %02x]", __func__, hdr->id0, hdr->id1); /* skip rest of buffer */ goto out; } ofs += hdr->length; rlen -= hdr->length; }