static void rmnet_usb_disconnect(struct usb_interface *intf)
{
	struct usbnet		*unet;
	struct usb_device	*udev;
	struct rmnet_ctrl_dev	*dev;

	udev = interface_to_usbdev(intf);
	device_set_wakeup_enable(&udev->dev, 0);

	unet = usb_get_intfdata(intf);
	if (!unet) {
		dev_err(&udev->dev, "%s:data device not found\n", __func__);
		return;
	}

	rmnet_usb_data_debugfs_cleanup(unet);

	dev = (struct rmnet_ctrl_dev *)unet->data[1];
	if (!dev) {
		dev_err(&udev->dev, "%s:ctrl device not found\n", __func__);
		return;
	}
#ifdef CONFIG_MDM_HSIC_PM
	unregister_udev_from_pm_dev(rmnet_pm_dev, udev);
#endif
	unet->data[0] = 0;
	unet->data[1] = 0;
	rmnet_usb_ctrl_disconnect(dev);
	device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
	usbnet_disconnect(intf);
}
Ejemplo n.º 2
0
static void rmnet_usb_disconnect(struct usb_interface *intf)
{
	struct usbnet		*unet;
	struct rmnet_ctrl_dev	*dev;

	unet = usb_get_intfdata(intf);
	if (!unet) {
		dev_err(&intf->dev, "%s:data device not found\n", __func__);
		return;
	}

	device_set_wakeup_enable(&unet->udev->dev, 0);
	rmnet_usb_data_debugfs_cleanup(unet);

	dev = (struct rmnet_ctrl_dev *)unet->data[1];
	if (!dev) {
		dev_err(&intf->dev, "%s:ctrl device not found\n", __func__);
		return;
	}
	unet->data[0] = 0;
	unet->data[1] = 0;
	rmnet_usb_ctrl_disconnect(dev);
	device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
	usbnet_disconnect(intf);
}
static void rmnet_usb_disconnect(struct usb_interface *intf)
{
	struct usbnet		*unet;
	struct usb_device	*udev;
	struct rmnet_ctrl_dev	*dev;

	udev = interface_to_usbdev(intf);

	unet = usb_get_intfdata(intf);
	if (!unet) {
		dev_err(&udev->dev, "%s:data device not found\n", __func__);
		return;
	}

	dev = (struct rmnet_ctrl_dev *)unet->data[1];
	if (!dev) {
		dev_err(&udev->dev, "%s:ctrl device not found\n", __func__);
		return;
	}
	unet->data[0] = 0;
	unet->data[1] = 0;
	rmnet_usb_ctrl_disconnect(dev);
	device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
	usbnet_disconnect(intf);
}
static void rmnet_usb_disconnect(struct usb_interface *intf)
{
	struct usbnet		*unet;
	struct rmnet_ctrl_dev	*dev;

	unet = usb_get_intfdata(intf);
	if (!unet) {
		dev_err(&intf->dev, "%s:data device not found\n", __func__);
		return;
	}

	device_set_wakeup_enable(&unet->udev->dev, 0);
	rmnet_usb_data_debugfs_cleanup(unet);

	dev = (struct rmnet_ctrl_dev *)unet->data[1];
	if (!dev) {
		dev_err(&intf->dev, "%s:ctrl device not found\n", __func__);
		return;
	}
	unet->data[0] = 0;
	unet->data[1] = 0;
	rmnet_usb_ctrl_disconnect(dev);
	device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
	usbnet_disconnect(intf);

//++SSD_RIL:20120814: For CPU/Freq min default value
	if ( rnmet_usb_cpu_freq_enabled == 1 ) {
		rmnet_usb_freq_release();
	}
//--SSD_RIL
}
Ejemplo n.º 5
0
void Gobinet_disconnect (struct usb_interface *pIntf)
{
	struct usbnet * pDev;
	sGobiUSBNet * pGobiDev;

	if (pIntf == 0)
	{
	  return -ENOMEM;
	}

#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,23 ))
	pDev = usb_get_intfdata( pIntf );
#else
	pDev = (struct usbnet *)pIntf->dev.platform_data;
#endif

	if (pDev == NULL || pDev->net == NULL)
	{
	  DBG( "failed to get netdevice\n" );
	  return -ENXIO;
	}

	pGobiDev = (sGobiUSBNet *)pDev->data[0];
	if (pGobiDev == NULL)
	{
	  DBG( "failed to get QMIDevice\n" );
	  return -ENXIO;
	}
#if 1
	DeregisterQMIDevice(pGobiDev);
#else
	cdev_del(&pGobiDev->mQMIDev.mCdev);
#endif
	usbnet_disconnect(pIntf);
}
Ejemplo n.º 6
0
static void rmnet_usb_disconnect(struct usb_interface *intf)
{
	struct usbnet		*unet = usb_get_intfdata(intf);
	struct rmnet_ctrl_dev	*dev;
	unsigned int		n, rdev_cnt, unet_id;
	struct driver_info	*info = unet->driver_info;
	bool			mux = unet->data[4];

	rdev_cnt = mux ? no_rmnet_insts_per_dev : 1;

	device_set_wakeup_enable(&unet->udev->dev, 0);

	for (n = 0; n < rdev_cnt; n++) {
		unet_id = n + info->data * no_rmnet_insts_per_dev;
		unet = mux ? unet_list[unet_id] : usb_get_intfdata(intf);
		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);

		dev = (struct rmnet_ctrl_dev *)unet->data[1];
		rmnet_usb_ctrl_disconnect(dev);
		unet->data[0] = 0;
		unet->data[1] = 0;
		rmnet_usb_data_debugfs_cleanup(unet);
		usb_set_intfdata(intf, unet);
		usbnet_disconnect(intf);
		unet_list[unet_id] = NULL;
	}
}
Ejemplo n.º 7
0
static void cdc_ncm_disconnect(struct usb_interface *intf)
{
	struct usbnet *dev = usb_get_intfdata(intf);

	if (dev == NULL)
		return;		/* already disconnected */

	usbnet_disconnect(intf);
}
Ejemplo n.º 8
0
static void rmnet_usb_disconnect(struct usb_interface *intf)
{
	struct usbnet		*unet = usb_get_intfdata(intf);
	struct rmnet_ctrl_udev	*dev;

	device_set_wakeup_enable(&unet->udev->dev, 0);

	device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);

	dev = (struct rmnet_ctrl_udev *)unet->data[1];
	rmnet_usb_ctrl_disconnect(dev);
	unet->data[0] = 0;
	unet->data[1] = 0;
	rmnet_usb_data_debugfs_cleanup(unet);
	usbnet_disconnect(intf);
}
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info = (struct driver_info *)prod->driver_info;
	struct usb_device	*udev;
	int			status = 0;
	unsigned int		i, unet_id, rdev_cnt, n = 0;
	bool			mux;
	struct rmnet_ctrl_dev	*dev;

	udev = interface_to_usbdev(iface);

	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	mux = test_bit(info->data, &mux_enabled);
	rdev_cnt = mux ? no_rmnet_insts_per_dev : 1;
	info->in = 0;

	for (n = 0; n < rdev_cnt; n++) {

		/* Use this filed to increment device count this will be
		 * used by bind to determin the forward link and reverse
		 * link network interface names.
		 */
		info->in++;
		status = usbnet_probe(iface, prod);
		if (status < 0) {
			dev_err(&iface->dev, "usbnet_probe failed %d\n",
					status);
			goto out;
		}

		unet_id = n + info->data * no_rmnet_insts_per_dev;

		unet_list[unet_id] = unet = usb_get_intfdata(iface);

		/*store mux id for later access*/
		unet->data[3] = n;

		/*save mux info for control and usbnet devices*/
		unet->data[1] = unet->data[4] = mux;

		/*set rmnet operation mode to eth by default*/
		set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

		/*update net device*/
		rmnet_usb_setup(unet->net, mux);

		/*create /sys/class/net/rmnet_usbx/dbg_mask*/
		status = device_create_file(&unet->net->dev,
				&dev_attr_dbg_mask);
		if (status) {
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_ctrl_probe(iface, unet->status, info->data,
				&unet->data[1]);
		if (status) {
			device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_data_debugfs_init(unet);
		if (status)
			dev_dbg(&iface->dev,
					"mode debugfs file is not available\n");
	}

	usb_enable_autosuspend(udev);

	if (udev->parent && !udev->parent->parent) {
		/* allow modem and roothub to wake up suspended system */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);
	}

	return 0;

out:
	for (i = 0; i < n; i++) {
		/* This cleanup happens only for MUX case */
		unet_id = i + info->data * no_rmnet_insts_per_dev;
		unet = unet_list[unet_id];
		dev = (struct rmnet_ctrl_dev *)unet->data[1];

		rmnet_usb_data_debugfs_cleanup(unet);
		rmnet_usb_ctrl_disconnect(dev);
		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
		usb_set_intfdata(iface, unet_list[unet_id]);
		usbnet_disconnect(iface);
		unet_list[unet_id] = NULL;
	}

	return status;
}
Ejemplo n.º 10
0
/*===========================================================================
METHOD:
   GobiUSBNetProbe (Public Method)

DESCRIPTION:
   Run usbnet_probe
   Setup QMI device

PARAMETERS
   pIntf        [ I ] - Pointer to interface
   pVIDPIDs     [ I ] - Pointer to VID/PID table

RETURN VALUE:
   int - 0 for success
         Negative errno for error
===========================================================================*/
int GobiUSBNetProbe(
   struct usb_interface *        pIntf,
   const struct usb_device_id *  pVIDPIDs )
{
   int is9x15 = 0;
   unsigned char    ifacenum;
   int status;
   struct usbnet * pDev;
   sGobiUSBNet * pGobiDev;
   struct ethhdr *eth;

#if 0
   /* There exists a race condition in the firmware that sometimes results
    * in the absence of Ethernet framing of packets received from the device.
    * Therefore, a firmware work-around currently hard-codes the MAC address
    * to ensure valid Ethernet frames are sent to the host. We therefore
    * hard-code the network device MAC address to comply with the firmware
    */
   const char default_addr[6] = {0x00, 0xa0, 0xc6, 0x00, 0x00, 0x00};
#endif

#if (LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,29 ))
   struct net_device_ops * pNetDevOps;
#endif

   ifacenum =  pIntf->cur_altsetting->desc.bInterfaceNumber;

   status = usbnet_probe( pIntf, pVIDPIDs );
   if (status < 0)
   {
      DBG( "usbnet_probe failed %d\n", status );
      return status;
   }

#if (LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,19 ))
   pIntf->needs_remote_wakeup = 1;
#endif

#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,23 ))
   pDev = usb_get_intfdata( pIntf );
#else
   pDev = (struct usbnet *)pIntf->dev.platform_data;
#endif

   if (pDev == NULL || pDev->net == NULL)
   {
      DBG( "failed to get netdevice\n" );
      usbnet_disconnect( pIntf );
      return -ENXIO;
   }

   pGobiDev = kmalloc( sizeof( sGobiUSBNet ), GFP_KERNEL );
   if (pGobiDev == NULL)
   {
      DBG( "falied to allocate device buffers" );
      usbnet_disconnect( pIntf );
      return -ENOMEM;
   }

   pDev->data[0] = (unsigned long)pGobiDev;

   pGobiDev->mpNetDev = pDev;

#ifdef DATA_MODE_RP
   pDev->net->flags |= IFF_NOARP;
   DBG( "RawIP mode\n" );
#endif

   // Clearing endpoint halt is a magic handshake that brings 
   // the device out of low power (airplane) mode
   // NOTE: FCC verification should be done before this, if required
   usb_clear_halt( pGobiDev->mpNetDev->udev, pDev->out );

   // Overload PM related network functions
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
   pGobiDev->mpUSBNetOpen = pDev->net->open;
   pDev->net->open = GobiUSBNetOpen;
   pGobiDev->mpUSBNetStop = pDev->net->stop;
   pDev->net->stop = GobiUSBNetStop;
   pDev->net->hard_start_xmit = GobiUSBNetStartXmit;
   pDev->net->tx_timeout = GobiUSBNetTXTimeout;
#else
   pNetDevOps = kmalloc( sizeof( struct net_device_ops ), GFP_KERNEL );
   if (pNetDevOps == NULL)
   {
      DBG( "falied to allocate net device ops" );
      usbnet_disconnect( pIntf );
      return -ENOMEM;
   }
   memcpy( pNetDevOps, pDev->net->netdev_ops, sizeof( struct net_device_ops ) );

   pGobiDev->mpUSBNetOpen = pNetDevOps->ndo_open;
   pNetDevOps->ndo_open = GobiUSBNetOpen;
   pGobiDev->mpUSBNetStop = pNetDevOps->ndo_stop;
   pNetDevOps->ndo_stop = GobiUSBNetStop;
#ifdef CONFIG_PM
   pNetDevOps->ndo_start_xmit = GobiUSBNetStartXmit;
   pNetDevOps->ndo_tx_timeout = GobiUSBNetTXTimeout;
#else
   pNetDevOps->ndo_start_xmit = usbnet_start_xmit;
   pNetDevOps->ndo_tx_timeout = usbnet_tx_timeout;
#endif /* CONFIG_PM */

   pDev->net->netdev_ops = pNetDevOps;
#endif

#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,31 ))
   memset( &(pGobiDev->mpNetDev->stats), 0, sizeof( struct net_device_stats ) );
#else
   memset( &(pGobiDev->mpNetDev->net->stats), 0, sizeof( struct net_device_stats ) );
#endif

   pGobiDev->mpIntf = pIntf;
   memset( &(pGobiDev->mMEID), '0', 14 );

   /* change MAC addr to include, ifacenum, and to be unique */
   pGobiDev->mpNetDev->net->dev_addr[ETH_ALEN-2] = atomic_inc_return(&iface_counter);
   pGobiDev->mpNetDev->net->dev_addr[ETH_ALEN-1] = ifacenum;

   DBG( "Mac Address:\n" );
   PrintHex( &pGobiDev->mpNetDev->net->dev_addr[0], 6 );
#if 0 /* interfers with multiple interface support and no longer appears to be necessary */
   /* Hard-code the host MAC address to comply with the firmware workaround */
   memcpy(&pGobiDev->mpNetDev->net->dev_addr[0], &default_addr[0], 6);
   DBG( "Default Mac Address:\n" );
   PrintHex( &pGobiDev->mpNetDev->net->dev_addr[0], 6 );
#endif
   /* Create ethernet header for IPv4 packets */
   eth = (struct ethhdr *)pGobiDev->eth_hdr_tmpl_ipv4;
   memcpy(&eth->h_dest, &pGobiDev->mpNetDev->net->dev_addr[0], ETH_ALEN);
   memcpy(&eth->h_source, &pGobiDev->mpNetDev->net->dev_addr[0], ETH_ALEN);
   eth->h_proto = cpu_to_be16(ETH_P_IP);

   /* Create ethernet header for IPv6 packets */
   eth = (struct ethhdr *)pGobiDev->eth_hdr_tmpl_ipv6;
   memcpy(&eth->h_dest, &pGobiDev->mpNetDev->net->dev_addr[0], ETH_ALEN);
   memcpy(&eth->h_source, &pGobiDev->mpNetDev->net->dev_addr[0], ETH_ALEN);
   eth->h_proto = cpu_to_be16(ETH_P_IPV6);

   pGobiDev->mbQMIValid = false;
   memset( &pGobiDev->mQMIDev, 0, sizeof( sQMIDev ) );
   pGobiDev->mQMIDev.mbCdevIsInitialized = false;

   pGobiDev->mQMIDev.mpDevClass = gpClass;

#ifdef CONFIG_PM
   init_completion( &pGobiDev->mAutoPM.mThreadDoWork );
#endif /* CONFIG_PM */
   spin_lock_init( &pGobiDev->mQMIDev.mClientMemLock );

   // Default to device down
   pGobiDev->mDownReason = 0;
   GobiSetDownReason( pGobiDev, NO_NDIS_CONNECTION );
   GobiSetDownReason( pGobiDev, NET_IFACE_STOPPED );

   // Register QMI
   if (pDev->driver_info->data &&
          test_bit(BIT_9X15, &pDev->driver_info->data)) {
       is9x15 = 1;
   }
   status = RegisterQMIDevice( pGobiDev, is9x15 );
   if (status != 0)
   {
      // usbnet_disconnect() will call GobiNetDriverUnbind() which will call
      // DeregisterQMIDevice() to clean up any partially created QMI device
      usbnet_disconnect( pIntf );
      return status;
   }

   // Success
   return 0;
}
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info = (struct driver_info *)prod->driver_info;
	struct usb_device	*udev;
	int			status = 0;
	unsigned int		i, unet_id, rdev_cnt, n = 0;
	bool			mux;
	struct rmnet_ctrl_dev	*dev;

	udev = interface_to_usbdev(iface);

	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	mux = test_bit(info->data, &mux_enabled);
	rdev_cnt = mux ? no_rmnet_insts_per_dev : 1;
	info->in = 0;

	for (n = 0; n < rdev_cnt; n++) {

		/*                                                      
                                                          
                                  
   */
		info->in++;
		status = usbnet_probe(iface, prod);
		if (status < 0) {
			dev_err(&iface->dev, "usbnet_probe failed %d\n",
					status);
			goto out;
		}

		unet_id = n + info->data * no_rmnet_insts_per_dev;

		unet_list[unet_id] = unet = usb_get_intfdata(iface);

		/*                             */
		unet->data[3] = n;

		/*                                            */
		unet->data[1] = unet->data[4] = mux;

		/*                                          */
		set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

		/*                 */
		rmnet_usb_setup(unet->net, mux);

		/*                                         */
		status = device_create_file(&unet->net->dev,
				&dev_attr_dbg_mask);
		if (status) {
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_ctrl_probe(iface, unet->status, info->data,
				&unet->data[1]);
		if (status) {
			device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_data_debugfs_init(unet);
		if (status)
			dev_dbg(&iface->dev,
					"mode debugfs file is not available\n");
	}

	usb_enable_autosuspend(udev);

	if (udev->parent && !udev->parent->parent) {
		/*                                                     */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);
	}

	return 0;

out:
	for (i = 0; i < n; i++) {
		/*                                        */
		unet_id = i + info->data * no_rmnet_insts_per_dev;
		unet = unet_list[unet_id];
		dev = (struct rmnet_ctrl_dev *)unet->data[1];

		rmnet_usb_data_debugfs_cleanup(unet);
		rmnet_usb_ctrl_disconnect(dev);
		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
		usb_set_intfdata(iface, unet_list[unet_id]);
		usbnet_disconnect(iface);
		unet_list[unet_id] = NULL;
	}

	return status;
}
Ejemplo n.º 12
0
/*===========================================================================
METHOD:
   GobiUSBNetProbe (Public Method)

DESCRIPTION:
   Run usbnet_probe
   Setup QMI device

PARAMETERS
   pIntf        [ I ] - Pointer to interface
   pVIDPIDs     [ I ] - Pointer to VID/PID table

RETURN VALUE:
   int - 0 for success
         Negative errno for error
===========================================================================*/
int GobiUSBNetProbe( 
   struct usb_interface *        pIntf, 
   const struct usb_device_id *  pVIDPIDs )
{
   int status;
   struct usbnet * pDev;
   sGobiUSBNet * pGobiDev;
   sEndpoints * pEndpoints;
   int pipe;
   
   unsigned char my_mac_addr[ETH_ALEN];
   struct sockaddr addr;
   
#if (LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,29 ))
   struct net_device_ops * pNetDevOps;
#endif

   pEndpoints = GatherEndpoints( pIntf );
   if (pEndpoints == NULL)
   {
      return -ENODEV;
   }      

   status = usbnet_probe( pIntf, pVIDPIDs );
   if (status < 0)
   {
      DBG( "usbnet_probe failed %d\n", status );
      return status;
   }

#if (LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,19 ))
   pIntf->needs_remote_wakeup = 1;
#endif

#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,23 ))
   pDev = usb_get_intfdata( pIntf );
#else
   pDev = (struct usbnet *)pIntf->dev.platform_data;
#endif

   if (pDev == NULL || pDev->net == NULL)
   {
      DBG( "failed to get netdevice\n" );
      usbnet_disconnect( pIntf );
      kfree( pEndpoints );
      return -ENXIO;
   }

//modify Mac from param arthur 20140122
if(mac_addr != NULL){
	
	str2mac(mac_addr,my_mac_addr);
	
	addr.sa_family = 1;
	memset(addr.sa_data,0,ETH_ALEN);
	memcpy(addr.sa_data, my_mac_addr, ETH_ALEN);
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
	pDev->net->set_mac_address(pDev->net,&addr);
#else	
	pDev->net->netdev_ops->ndo_set_mac_address(pDev->net,&addr);
#endif
}
//check the first 4 bits of MAC addr , for they can't be 4 or 6 arthur 20140122
if(((pDev->net->dev_addr[0] & 0xf0) == 0x40) ||
	((pDev->net->dev_addr[0] & 0xf0) == 0x60))
{
	printk("Need to Modify Mac\n" );
	
	addr.sa_family = 1;
	memset(addr.sa_data,0,ETH_ALEN);
	memcpy(addr.sa_data, pDev->net->dev_addr, ETH_ALEN);
	addr.sa_data[0] |= 0x10;
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
	pDev->net->set_mac_address(pDev->net,&addr);
#else	
	pDev->net->netdev_ops->ndo_set_mac_address(pDev->net,&addr);
#endif
}

   pGobiDev = kmalloc( sizeof( sGobiUSBNet ), GFP_KERNEL );
   if (pGobiDev == NULL)
   {
      DBG( "falied to allocate device buffers" );
      usbnet_disconnect( pIntf );
      kfree( pEndpoints );
      return -ENOMEM;
   }
   
   pDev->data[0] = (unsigned long)pGobiDev;
   
   pGobiDev->mpNetDev = pDev;
   pGobiDev->mpEndpoints = pEndpoints;

   // Clearing endpoint halt is a magic handshake that brings 
   // the device out of low power (airplane) mode
   // NOTE: FCC verification should be done before this, if required
   pipe = usb_sndbulkpipe( pGobiDev->mpNetDev->udev,
                           pGobiDev->mpEndpoints->mBlkOutEndp );
   usb_clear_halt( pGobiDev->mpNetDev->udev, pipe );

   // Overload PM related network functions
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
   pGobiDev->mpUSBNetOpen = pDev->net->open;
   pDev->net->open = GobiUSBNetOpen;
   pGobiDev->mpUSBNetStop = pDev->net->stop;
   pDev->net->stop = GobiUSBNetStop;
//   pDev->net->hard_start_xmit = GobiUSBNetStartXmit;
//   pDev->net->tx_timeout = GobiUSBNetTXTimeout;
#else
   pNetDevOps = kmalloc( sizeof( struct net_device_ops ), GFP_KERNEL );
   if (pNetDevOps == NULL)
   {
      DBG( "falied to allocate net device ops" );
      usbnet_disconnect( pIntf );
      return -ENOMEM;
   }
   memcpy( pNetDevOps, pDev->net->netdev_ops, sizeof( struct net_device_ops ) );
   
   pGobiDev->mpUSBNetOpen = pNetDevOps->ndo_open;
   pNetDevOps->ndo_open = GobiUSBNetOpen;
   pGobiDev->mpUSBNetStop = pNetDevOps->ndo_stop;
   pNetDevOps->ndo_stop = GobiUSBNetStop;
//   pNetDevOps->ndo_start_xmit = GobiUSBNetStartXmit;
//   pNetDevOps->ndo_tx_timeout = GobiUSBNetTXTimeout;

   pDev->net->netdev_ops = pNetDevOps;
#endif

#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,31 ))
   memset( &(pGobiDev->mpNetDev->stats), 0, sizeof( struct net_device_stats ) );
#else
   memset( &(pGobiDev->mpNetDev->net->stats), 0, sizeof( struct net_device_stats ) );
#endif

   pGobiDev->mpIntf = pIntf;
   memset( &(pGobiDev->mMEID), '0', 14 );
   
   DBG( "Mac Address:\n" );
   PrintHex( &pGobiDev->mpNetDev->net->dev_addr[0], 6 );

   pGobiDev->mbQMIValid = false;
   memset( &pGobiDev->mQMIDev, 0, sizeof( sQMIDev ) );
   pGobiDev->mQMIDev.mbCdevIsInitialized = false;

   pGobiDev->mQMIDev.mpDevClass = gpClass;
   
   init_completion( &pGobiDev->mAutoPM.mThreadDoWork );
   spin_lock_init( &pGobiDev->mQMIDev.mClientMemLock );

   // Default to device down
   pGobiDev->mDownReason = 0;
   GobiSetDownReason( pGobiDev, NO_NDIS_CONNECTION );
   GobiSetDownReason( pGobiDev, NET_IFACE_STOPPED );

   // Register QMI
   status = RegisterQMIDevice( pGobiDev );
   if (status != 0)
   {
      // usbnet_disconnect() will call GobiNetDriverUnbind() which will call
      // DeregisterQMIDevice() to clean up any partially created QMI device
      usbnet_disconnect( pIntf );
      return status;
   }
   
   // Success
   return 0;
}
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info;
	struct usb_device	*udev;
	unsigned int		iface_num;
	static int		first_rmnet_iface_num = -EINVAL;
	int			status = 0;

//++SSD_RIL:20120731: For tx/rx enable_hlt/disable_hlt
	if( machine_is_evitareul() ) {
		rnmet_usb_hlt_enabled = 1;
		pr_info("%s:rnmet_usb_hlt_enabled = 1\n", __func__);
	}
//--SSD_RIL
//++SSD_RIL:20120814: For CPU/Freq min default value
	if ( rnmet_usb_hlt_enabled == 1 && get_radio_flag() & 0x0002 ) {
		rnmet_usb_cpu_freq_enabled = 1;
	}
//--SSD_RIL

	iface_num = iface->cur_altsetting->desc.bInterfaceNumber;
	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	info = (struct driver_info *)prod->driver_info;
	if (!test_bit(iface_num, &info->data))
		return -ENODEV;

	status = usbnet_probe(iface, prod);
	if (status < 0) {
		dev_err(&iface->dev, "usbnet_probe failed %d\n", status);
		goto out;
	}
	unet = usb_get_intfdata(iface);

	/*set rmnet operation mode to eth by default*/
	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

	/*update net device*/
	rmnet_usb_setup(unet->net);

	/*create /sys/class/net/rmnet_usbx/dbg_mask*/
	status = device_create_file(&unet->net->dev, &dev_attr_dbg_mask);
	if (status)
		goto out;

	if (first_rmnet_iface_num == -EINVAL)
		first_rmnet_iface_num = iface_num;

	/*save control device intstance */
	unet->data[1] = (unsigned long)ctrl_dev	\
			[iface_num - first_rmnet_iface_num];

	status = rmnet_usb_ctrl_probe(iface, unet->status,
		(struct rmnet_ctrl_dev *)unet->data[1]);
	if (status)
		goto out;

	status = rmnet_usb_data_debugfs_init(unet);
	if (status)
		dev_dbg(&iface->dev, "mode debugfs file is not available\n");

	udev = unet->udev;

	if (udev->parent && !udev->parent->parent) {
		/* allow modem and roothub to wake up suspended system */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);

		/* set default autosuspend timeout for modem and roothub */
		pm_runtime_set_autosuspend_delay(&udev->dev, 1000);
		dev_err(&udev->dev, "pm_runtime_set_autosuspend_delay 1000\n");
		pm_runtime_set_autosuspend_delay(&udev->parent->dev, 200);
		dev_err(&udev->parent->dev, "pm_runtime_set_autosuspend_delay 200\n");
	}

out:
//++SSD_RIL:20120814: For CPU/Freq min default value
	if ( rnmet_usb_cpu_freq_enabled == 1 ) {
		rmnet_usb_freq_request();
	}
//--SSD_RIL


//++SSD_RIL:20121017: get -71 but already register rmnet netdev
if (status == -EPROTO && already_register_rmNET  ) {
	pr_info("%s fail ,status = %d,unregister_netdev \n", __func__,status);
	//unregister_netdev(unet->net);
	//usb_put_dev(unet->udev);
	usbnet_disconnect(iface);
}
//--SSD_RIL:20121017: get -71 but already register rmnet netdev

	return status;
}
Ejemplo n.º 14
0
/*===========================================================================
METHOD:
   QCUSBNetProbe (Public Method)

DESCRIPTION:
   Run usbnet_probe
   Setup QMI device

PARAMETERS
   pIntf        [ I ] - Pointer to interface
   pVIDPIDs     [ I ] - Pointer to VID/PID table

RETURN VALUE:
   int - 0 for success
         Negative errno for error
===========================================================================*/
int QCUSBNetProbe( 
   struct usb_interface *        pIntf, 
   const struct usb_device_id *  pVIDPIDs )
{
   int status;
   struct usbnet * pDev;
   sQCUSBNet * pQCDev;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,29 ))
   struct net_device_ops * pNetDevOps;
#endif
   int i;
   u8 *addr;

   status = usbnet_probe( pIntf, pVIDPIDs );
   if(status < 0 )
   {
      DBG( "usbnet_probe failed %d\n", status );
      return status;
   }

#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,23 ))
   pDev = usb_get_intfdata( pIntf );
#else
   pDev = (struct usbnet *)pIntf->dev.platform_data;
#endif

   if (pDev == NULL || pDev->net == NULL)
   {
      DBG( "failed to get netdevice\n" );
      usbnet_disconnect( pIntf );
      return -ENXIO;
   }

   pQCDev = kmalloc( sizeof( sQCUSBNet ), GFP_KERNEL );
   if (pQCDev == NULL)
   {
      DBG( "falied to allocate device buffers" );
      usbnet_disconnect( pIntf );
      return -ENOMEM;
   }
   
   pDev->data[0] = (unsigned long)pQCDev;
   
   pQCDev->mpNetDev = pDev;

   // Overload PM related network functions
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
   pQCDev->mpUSBNetOpen = pDev->net->open;
   pDev->net->open = QCUSBNetOpen;
   pQCDev->mpUSBNetStop = pDev->net->stop;
   pDev->net->stop = QCUSBNetStop;
   pDev->net->hard_start_xmit = QCUSBNetStartXmit;
   pDev->net->tx_timeout = QCUSBNetTXTimeout;
#else
   pNetDevOps = kmalloc( sizeof( struct net_device_ops ), GFP_KERNEL );
   if (pNetDevOps == NULL)
   {
      DBG( "falied to allocate net device ops" );
      usbnet_disconnect( pIntf );
      return -ENOMEM;
   }
   memcpy( pNetDevOps, pDev->net->netdev_ops, sizeof( struct net_device_ops ) );
   
   pQCDev->mpUSBNetOpen = pNetDevOps->ndo_open;
   pNetDevOps->ndo_open = QCUSBNetOpen;
   pQCDev->mpUSBNetStop = pNetDevOps->ndo_stop;
   pNetDevOps->ndo_stop = QCUSBNetStop;
   pNetDevOps->ndo_start_xmit = QCUSBNetStartXmit;
   pNetDevOps->ndo_tx_timeout = QCUSBNetTXTimeout;

   pDev->net->netdev_ops = pNetDevOps;
#endif

#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,31 ))
   memset( &(pQCDev->mpNetDev->stats), 0, sizeof( struct net_device_stats ) );
#else
   memset( &(pQCDev->mpNetDev->net->stats), 0, sizeof( struct net_device_stats ) );
#endif

   pQCDev->mpIntf = pIntf;
   memset( &(pQCDev->mMEID), '0', 14 );

   pQCDev->mbQMIValid = false;
   memset( &pQCDev->mQMIDev, 0, sizeof( sQMIDev ) );
   pQCDev->mQMIDev.mbCdevIsInitialized = false;

   pQCDev->mQMIDev.mpDevClass = gpClass;
   
   init_completion( &pQCDev->mAutoPM.mThreadDoWork );
   spin_lock_init( &pQCDev->mQMIDev.mClientMemLock );

   // Default to device down
   pQCDev->mDownReason = 0;
   QSetDownReason( pQCDev, NO_NDIS_CONNECTION );
   QSetDownReason( pQCDev, NET_IFACE_STOPPED );

   // Register QMI
   status = RegisterQMIDevice( pQCDev );
   if (status != 0)
   {
      // usbnet_disconnect() will call QCUSBNetUnbind() which will call
      // DeregisterQMIDevice() to clean up any partially created QMI device
      usbnet_disconnect( pIntf );
      return status;
   }

   // After calling RegisterQMIDevice mMEID is valid.  Although most
   // drivers set the MAC address in bind(), we need to wait until the
   // MEID is available.
   addr = &pDev->net->dev_addr[0];
   for (i = 0; i < 6; i++)
     addr[i] = (nibble(pQCDev->mMEID[i*2+2]) << 4) +
         nibble(pQCDev->mMEID[i*2+3]);
   addr [0] &= 0xfe;       /* clear multicast bit */
   addr [0] |= 0x02;       /* set local assignment bit (IEEE802) */

   DBG( "Mac Address:\n" );
   PrintHex( &pQCDev->mpNetDev->net->dev_addr[0], 6 );

   // Success
   return 0;
}
Ejemplo n.º 15
0
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info = (struct driver_info *)prod->driver_info;
	struct usb_device	*udev;
	int			status = 0;
	unsigned int		i, unet_id, rdev_cnt, n = 0;
	bool			mux;
	struct rmnet_ctrl_dev	*dev;

	udev = interface_to_usbdev(iface);

	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		status = -EINVAL;
		goto out;
	}

	mux = test_bit(info->data, &mux_enabled);
	
	if (prod->idProduct == 0x908a)
		mux = true;
	else
		mux = false;

	mux_enabled_per_pid = mux;
	
	rdev_cnt = mux ? no_rmnet_insts_per_dev : 1;
	info->in = 0;

	for (n = 0; n < rdev_cnt; n++) {

		info->in++;
		status = usbnet_probe(iface, prod);
		if (status < 0) {
			dev_err(&iface->dev, "usbnet_probe failed %d\n",
					status);
			goto out;
		}

		unet_id = n + info->data * no_rmnet_insts_per_dev;

		unet_list[unet_id] = unet = usb_get_intfdata(iface);

		
		unet->data[3] = n;

		
		unet->data[1] = unet->data[4] = mux;

		
		set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

		
		rmnet_usb_setup(unet->net, mux);

		
		status = device_create_file(&unet->net->dev,
				&dev_attr_dbg_mask);
		if (status) {
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_ctrl_probe(iface, unet->status, info->data,
				&unet->data[1]);
		if (status) {
			device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
			usbnet_disconnect(iface);
			goto out;
		}

		status = rmnet_usb_data_debugfs_init(unet);
		if (status)
			dev_dbg(&iface->dev,
					"mode debugfs file is not available\n");
	}
	
	

	if (udev->parent && !udev->parent->parent) {
		
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);

		
		pm_runtime_set_autosuspend_delay(&udev->dev, 1000);
		pm_runtime_set_autosuspend_delay(&udev->parent->dev, 200);

		#if defined(CONFIG_MONITOR_STREAMING_PORT_SOCKET) && defined(CONFIG_MSM_NONSMD_PACKET_FILTER)
		original_autosuspend_timer = udev->dev.power.autosuspend_delay;
		dev_info(&udev->dev, "original_autosuspend_timer:%d\n", original_autosuspend_timer);
		#endif 
	}

	return 0;

out:
	for (i = 0; i < n; i++) {
		
		unet_id = i + info->data * no_rmnet_insts_per_dev;
		unet = unet_list[unet_id];
		dev = (struct rmnet_ctrl_dev *)unet->data[1];

		rmnet_usb_data_debugfs_cleanup(unet);
		rmnet_usb_ctrl_disconnect(dev);
		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
		usb_set_intfdata(iface, unet_list[unet_id]);
		usbnet_disconnect(iface);
		unet_list[unet_id] = NULL;
	}

	return status;
}
Ejemplo n.º 16
0
/*===========================================================================
METHOD:
   GobiUSBNetProbe (Public Method)

DESCRIPTION:
   Run usbnet_probe
   Setup QMI device

PARAMETERS
   pIntf        [ I ] - Pointer to interface
   pVIDPIDs     [ I ] - Pointer to VID/PID table

RETURN VALUE:
   int - 0 for success
         Negative errno for error
===========================================================================*/
int GobiUSBNetProbe( 
   struct usb_interface *        pIntf, 
   const struct usb_device_id *  pVIDPIDs )
{
   int status;
   struct usbnet * pDev;
   sGobiUSBNet * pGobiDev;
#if (LINUX_VERSION_CODE >= KERNEL_VERSION( 2,6,29 ))
   struct net_device_ops * pNetDevOps;
#endif

   status = usbnet_probe( pIntf, pVIDPIDs );
   if(status < 0 )
   {
      DBG( "usbnet_probe failed %d\n", status );
      return status;
   }

#if (LINUX_VERSION_CODE > KERNEL_VERSION( 2,6,23 ))
   pDev = usb_get_intfdata( pIntf );
#else
   pDev = (struct usbnet *)pIntf->dev.platform_data;
#endif

   if (pDev == NULL || pDev->net == NULL)
   {
      DBG( "failed to get netdevice\n" );
      usbnet_disconnect( pIntf );
      return -ENXIO;
   }

   pGobiDev = kmalloc( sizeof( sGobiUSBNet ), GFP_KERNEL );
   if (pGobiDev == NULL)
   {
      DBG( "falied to allocate device buffers" );
      usbnet_disconnect( pIntf );
      return -ENOMEM;
   }
   
   pDev->data[0] = (unsigned long)pGobiDev;
   
   pGobiDev->mpNetDev = pDev;

   // Overload PM related network functions
#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,29 ))
   pGobiDev->mpUSBNetOpen = pDev->net->open;
   pDev->net->open = GobiUSBNetOpen;
   pGobiDev->mpUSBNetStop = pDev->net->stop;
   pDev->net->stop = GobiUSBNetStop;
   pDev->net->hard_start_xmit = GobiUSBNetStartXmit;
   pDev->net->tx_timeout = GobiUSBNetTXTimeout;
#else
   pNetDevOps = kmalloc( sizeof( struct net_device_ops ), GFP_KERNEL );
   if (pNetDevOps == NULL)
   {
      DBG( "falied to allocate net device ops" );
      usbnet_disconnect( pIntf );
      return -ENOMEM;
   }
   memcpy( pNetDevOps, pDev->net->netdev_ops, sizeof( struct net_device_ops ) );
   
   pGobiDev->mpUSBNetOpen = pNetDevOps->ndo_open;
   pNetDevOps->ndo_open = GobiUSBNetOpen;
   pGobiDev->mpUSBNetStop = pNetDevOps->ndo_stop;
   pNetDevOps->ndo_stop = GobiUSBNetStop;
   pNetDevOps->ndo_start_xmit = GobiUSBNetStartXmit;
   pNetDevOps->ndo_tx_timeout = GobiUSBNetTXTimeout;

   pDev->net->netdev_ops = pNetDevOps;
#endif

#if (LINUX_VERSION_CODE < KERNEL_VERSION( 2,6,31 ))
   memset( &(pGobiDev->mpNetDev->stats), 0, sizeof( struct net_device_stats ) );
#else
   memset( &(pGobiDev->mpNetDev->net->stats), 0, sizeof( struct net_device_stats ) );
#endif

   pGobiDev->mpIntf = pIntf;
   memset( &(pGobiDev->mMEID), '0', 14 );
   
   DBG( "Mac Address:\n" );
   PrintHex( &pGobiDev->mpNetDev->net->dev_addr[0], 6 );

   pGobiDev->mbQMIValid = false;
   memset( &pGobiDev->mQMIDev, 0, sizeof( sQMIDev ) );
   pGobiDev->mQMIDev.mbCdevIsInitialized = false;

   pGobiDev->mQMIDev.mpDevClass = gpClass;
   
   init_completion( &pGobiDev->mAutoPM.mThreadDoWork );
   spin_lock_init( &pGobiDev->mQMIDev.mClientMemLock );

   // Default to device down
   pGobiDev->mDownReason = 0;
   GobiSetDownReason( pGobiDev, NO_NDIS_CONNECTION );
   GobiSetDownReason( pGobiDev, NET_IFACE_STOPPED );

   // Register QMI
   status = RegisterQMIDevice( pGobiDev );
   if (status != 0)
   {
      // usbnet_disconnect() will call GobiNetDriverUnbind() which will call
      // DeregisterQMIDevice() to clean up any partially created QMI device
      usbnet_disconnect( pIntf );
      return status;
   }
   
   // Success
   return 0;
}
Ejemplo n.º 17
0
static int rmnet_usb_probe(struct usb_interface *iface,
		const struct usb_device_id *prod)
{
	struct usbnet		*unet;
	struct driver_info	*info = (struct driver_info *)prod->driver_info;
	struct usb_device	*udev;
	int			status = 0;

	udev = interface_to_usbdev(iface);

	if (iface->num_altsetting != 1) {
		dev_err(&iface->dev, "%s invalid num_altsetting %u\n",
			__func__, iface->num_altsetting);
		return -EINVAL;
	}

	status = usbnet_probe(iface, prod);
	if (status < 0) {
		dev_err(&iface->dev, "usbnet_probe failed %d\n",
				status);
		return status;
	}

	unet = usb_get_intfdata(iface);

	/*set rmnet operation mode to eth by default*/
	set_bit(RMNET_MODE_LLP_ETH, &unet->data[0]);

	/*update net device*/
	rmnet_usb_setup(unet->net);

	/*create /sys/class/net/rmnet_usbx/dbg_mask*/
	status = device_create_file(&unet->net->dev,
			&dev_attr_dbg_mask);
	if (status) {
		usbnet_disconnect(iface);
		return status;
	}

	status = rmnet_usb_ctrl_probe(iface, unet->status, info->data,
			&unet->data[1]);
	if (status) {
		device_remove_file(&unet->net->dev, &dev_attr_dbg_mask);
		usbnet_disconnect(iface);
		return status;
	}

	status = rmnet_usb_data_debugfs_init(unet);
	if (status)
		dev_dbg(&iface->dev,
				"mode debugfs file is not available\n");

	usb_enable_autosuspend(udev);

	if (udev->parent && !udev->parent->parent) {
		/* allow modem and roothub to wake up suspended system */
		device_set_wakeup_enable(&udev->dev, 1);
		device_set_wakeup_enable(&udev->parent->dev, 1);
	}

	return 0;
}