static void rx_fixup(unsigned long data) { pegasus_t *pegasus; unsigned long flags; pegasus = (pegasus_t *) data; if (pegasus->flags & PEGASUS_UNPLUG) return; spin_lock_irqsave(&pegasus->rx_pool_lock, flags); fill_skb_pool(pegasus); if (pegasus->flags & PEGASUS_RX_URB_FAIL) if (pegasus->rx_skb) goto try_again; if (pegasus->rx_skb == NULL) { pegasus->rx_skb = pull_skb(pegasus); } if (pegasus->rx_skb == NULL) { warn("wow, low on memory"); tasklet_schedule(&pegasus->rx_tl); goto done; } usb_fill_bulk_urb(pegasus->rx_urb, pegasus->usb, usb_rcvbulkpipe(pegasus->usb, 1), pegasus->rx_skb->data, PEGASUS_MTU + 8, read_bulk_callback, pegasus); try_again: if (usb_submit_urb(pegasus->rx_urb, GFP_ATOMIC)) { pegasus->flags |= PEGASUS_RX_URB_FAIL; tasklet_schedule(&pegasus->rx_tl); } else { pegasus->flags &= ~PEGASUS_RX_URB_FAIL; } done: spin_unlock_irqrestore(&pegasus->rx_pool_lock, flags); }
static int pegasus_probe(struct usb_interface *intf, const struct usb_device_id *id) { struct usb_device *dev = interface_to_usbdev(intf); struct net_device *net; pegasus_t *pegasus; int dev_index = id - pegasus_ids; int res = -ENOMEM; usb_get_dev(dev); if (!(pegasus = kmalloc(sizeof (struct pegasus), GFP_KERNEL))) { err("out of memory allocating device structure"); goto out; } memset(pegasus, 0, sizeof (struct pegasus)); pegasus->dev_index = dev_index; init_waitqueue_head(&pegasus->ctrl_wait); if (!alloc_urbs(pegasus)) goto out1; net = alloc_etherdev(0); if (!net) goto out2; tasklet_init(&pegasus->rx_tl, rx_fixup, (unsigned long) pegasus); pegasus->usb = dev; pegasus->net = net; SET_MODULE_OWNER(net); net->priv = pegasus; net->open = pegasus_open; net->stop = pegasus_close; net->watchdog_timeo = PEGASUS_TX_TIMEOUT; net->tx_timeout = pegasus_tx_timeout; net->do_ioctl = pegasus_ioctl; net->hard_start_xmit = pegasus_start_xmit; net->set_multicast_list = pegasus_set_multicast; net->get_stats = pegasus_netdev_stats; net->mtu = PEGASUS_MTU; pegasus->mii.dev = net; pegasus->mii.mdio_read = mdio_read; pegasus->mii.mdio_write = mdio_write; pegasus->mii.phy_id_mask = 0x1f; pegasus->mii.reg_num_mask = 0x1f; spin_lock_init(&pegasus->rx_pool_lock); pegasus->features = usb_dev_id[dev_index].private; get_interrupt_interval(pegasus); if (reset_mac(pegasus)) { err("can't reset MAC"); res = -EIO; goto out3; } set_ethernet_addr(pegasus); fill_skb_pool(pegasus); if (pegasus->features & PEGASUS_II) { info("setup Pegasus II specific registers"); setup_pegasus_II(pegasus); } pegasus->phy = mii_phy_probe(pegasus); if (pegasus->phy == 0xff) { warn("can't locate MII phy, using default"); pegasus->phy = 1; } usb_set_intfdata(intf, pegasus); SET_NETDEV_DEV(net, &intf->dev); res = register_netdev(net); if (res) goto out4; printk("%s: %s\n", net->name, usb_dev_id[dev_index].name); return 0; out4: usb_set_intfdata(intf, NULL); free_skb_pool(pegasus); out3: free_netdev(net); out2: free_all_urbs(pegasus); out1: kfree(pegasus); out: usb_put_dev(dev); return res; }
unsigned int processSdioReceiveData(MINIPORT_ADAPTER *Adapter, void *Buffer, u_long Length, long Timeout) { unsigned int offset = 0, PacketLen = 0, remain_len = 0; PHW_PACKET_HEADER hdr = (PHW_PACKET_HEADER)Buffer; unsigned long PacketType; struct net_device *net = Adapter->net; u_long flags; ENTER; DumpDebug(RX_DPC,"Total length of packet = %lu", Length); PacketType = HwPktTypeNone; PacketLen = Length; #if 0 if(Adapter->bHaltPending) return 0; #endif if (hdr->Id0 != 'W') { // "WD", "WC", "WP" or "WE" DumpDebug(RX_DPC, "WiBro USB: Wrong packet ID (%c%c or %02x%02x)", hdr->Id0, hdr->Id1, hdr->Id0, hdr->Id1); // skip rest of packets PacketLen = 0; } // check packet type if ((hdr->Id0 == 'W') && (hdr->Id1 == 'P')) { DumpDebug(RX_DPC, "WiBro USB: control packet (private) "); // set packet type PacketType = HwPktTypePrivate; } else if ((hdr->Id0 == 'W') && (hdr->Id1 == 'C')) { DumpDebug(RX_DPC, "WiBro USB: CONTROL packet <<<-----------------------------------"); PacketType = HwPktTypeControl; } else if ((hdr->Id0 == 'W') && (hdr->Id1 == 'D')) { DumpDebug(RX_DPC, "WiBro USB: DATA packet <<<-------------------------------------------------------------------"); PacketType = HwPktTypeData; } else { DumpDebug(RX_DPC, "WiBro USB: Wrong packet ID (%c%c or %02x%02x)", hdr->Id0, hdr->Id1, hdr->Id0, hdr->Id1); return 0; } if (PacketType != HwPktTypePrivate) { if (!Adapter->DownloadMode) { if (hdr->Length > MINIPORT_MAX_TOTAL_SIZE) { DumpDebug(RX_DPC,"WiBro USB: Packet length is too big (%d)", hdr->Length); // skip rest of packets PacketLen = 0; } } if (hdr->Length) { // change offset offset += sizeof(HW_PACKET_HEADER); #ifdef HARDWARE_USE_ALIGN_HEADER if(!Adapter->DownloadMode) offset += 2; #endif if(PacketLen <4 ) { PacketLen = 0; return 0; } PacketLen -= offset; /* from this line, Packet length is read data size without samsung header YHM */ // copy packet #ifdef HARDWARE_USE_SUPPRESS_MAC_HEADER //sangam dbg:If suppress mac address enabled during send same applicable to receive memcpy((unsigned char *)Adapter->hw.ReceiveBuffer, Adapter->hw.EthHeader, MINIPORT_LENGTH_OF_ADDRESS * 2); memcpy((unsigned char *)Adapter->hw.ReceiveBuffer + (MINIPORT_LENGTH_OF_ADDRESS * 2), ((unsigned char *) Buffer) + offset, PacketLen); PacketLen += (MINIPORT_LENGTH_OF_ADDRESS * 2); #else memcpy((unsigned char *)Adapter->hw.ReceiveBuffer, ((unsigned char *) Buffer) + offset, PacketLen); #endif if(PacketType == HwPktTypeData) { if (Adapter->rx_skb == NULL) { spin_lock_irqsave(&Adapter->rx_pool_lock, flags); fill_skb_pool(Adapter); Adapter->rx_skb = pull_skb(Adapter); spin_unlock_irqrestore(&Adapter->rx_pool_lock, flags); if(Adapter->rx_skb == NULL ){ DumpDebug(RX_DPC, "%s : Low on Memory",Adapter->net->name); return -ENOMEM; } } memcpy((unsigned char *)Adapter->rx_skb->data, (unsigned char *)Adapter->hw.ReceiveBuffer, PacketLen); #ifdef HARDWARE_USE_SUPPRESS_MAC_HEADER if(hdr->Length == (PacketLen - (MINIPORT_LENGTH_OF_ADDRESS * 2))) #else if(hdr->Length == PacketLen) #endif DumpDebug(RX_DPC,"Just one DATA packet processed and remained len is = %d",(PacketLen - hdr->Length)) else { remain_len = PacketLen - hdr->Length; DumpDebug(RX_DPC,"multiple DATA packet received and remained len is = %d",remain_len); } } else { #ifdef HARDWARE_USE_SUPPRESS_MAC_HEADER if(hdr->Length == (PacketLen - (MINIPORT_LENGTH_OF_ADDRESS * 2))) #else if(hdr->Length == PacketLen) #endif DumpDebug(RX_DPC,"Just one C or P packet processed and remained len is = %d", (PacketLen - hdr->Length)) else{ remain_len = PacketLen - hdr->Length; DumpDebug(RX_DPC,"multiple C or P packet received and remained len is = %d",remain_len); } } }