Ejemplo n.º 1
0
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);
}
Ejemplo n.º 2
0
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;
}
Ejemplo n.º 3
0
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);
				}				
			}
		}