static void smsnet_set_multicast_list(struct net_device *dev)
{
#if LINUX_VERSION_CODE >= KERNEL_VERSION(2, 6, 34)
    int mc_count = netdev_mc_count(dev);
	sms_info("mc count %d", mc_count);

	if (!netdev_mc_empty(dev)) {
		struct netdev_hw_addr *ha;

		netdev_for_each_mc_addr(ha, dev)
		sms_info(
			"%02x %02x %02x %02x %02x %02x %02x %02x",
			ha->addr[0],
			ha->addr[1], ha->addr[2],
			ha->addr[3], ha->addr[4],
			ha->addr[5], ha->addr[6], ha->addr[7]
			);
	}
#else
	sms_info("mc count %d", dev->mc_count);
	if (dev->mc_count) {
		struct dev_mc_list *p;

		for (p = dev->mc_list; p; p = p->next)
			sms_info(
			"%d %02x %02x %02x %02x %02x %02x %02x %02x",
			p->dmi_addrlen, p->dmi_addr[0],
			p->dmi_addr[1], p->dmi_addr[2],
			p->dmi_addr[3], p->dmi_addr[4],
			p->dmi_addr[5], p->dmi_addr[6], p->dmi_addr[7]
			);
	}
#endif
}
void smsspi_unregister(void)
{
    struct _spi_device_st *spi_device = spi_dev;
    sms_info("entering\n");

    /* stop interrupts */
    smsspiphy_deinit(spi_device->phy_dev);
    smscore_unregister_device(spi_device->coredev);

    dma_free_coherent(NULL, TX_BUFFER_SIZE, spi_device->txbuf,
                      spi_device->txbuf_phy_addr);

    platform_device_unregister(&smsspi_device);
    sms_info("exiting\n");
}
/**
 * smschar callback that called when device plugged in/out. the function
 * register or unregisters char device interface according to plug in/out
 *
 * @param coredev pointer to device that is being plugged in/out
 * @param device pointer to system device object
 * @param arrival 1 on plug-on, 0 othewise
 *
 * @return 0 on success, <0 on error.
 */
static int smschar_hotplug(struct smscore_device_t *coredev,
			   struct device *device, int arrival)
{
	int rc = 0, i;

	sms_info("entering %d", arrival);

	g_pnp_status_changed = 1;
	if (arrival) {
		/* currently only 1 instance supported */
		if (!g_smschar_inuse) {
			/* data notification callbacks assignment */
			memset(smschar_devices, 0, SMSCHAR_NR_DEVS *
			       sizeof(struct smschar_device_t));

			/* Initialize each device. */
			for (i = 0; i < SMSCHAR_NR_DEVS; i++) {
				sms_info("create device %d", i);
				smschar_setup_cdev(&smschar_devices[i], i);
				INIT_LIST_HEAD(&smschar_devices[i].
					       pending_data);
				spin_lock_init(&smschar_devices[i].lock);
				init_waitqueue_head(&smschar_devices[i].waitq);

				smschar_devices[i].coredev = coredev;
				smschar_devices[i].device_index = i;
			}
			g_smschar_inuse = 1;
			wake_up_interruptible(&g_pnp_event);
		}
	} else {
		/* currently only 1 instance supported */
		if (g_smschar_inuse) {
			/* Get rid of our char dev entries */
			for (i = 0; i < SMSCHAR_NR_DEVS; i++) {
				cdev_del(&smschar_devices[i].cdev);
				sms_info("remove device %d", i);
			}

			g_smschar_inuse = 0;
			wake_up_interruptible(&g_pnp_event);
		}
	}

	sms_info("exiting, rc %d", rc);

	return rc;		/* succeed */
}
static int smsnet_stop(struct net_device *dev)
{
	netif_stop_queue(dev);
	g_smsnet_inuse--;
	sms_info("smsnet in use %d", g_smsnet_inuse);
	return 0;
}
/**
 * registers client associated with the node
 *
 * @param inode Inode concerned.
 * @param file File concerned.
 *
 * @return 0 on success, <0 on error.
 */
static int smschar_open(struct inode *inode, struct file *file)
{
	struct smschar_device_t *dev = container_of(inode->i_cdev,
						    struct smschar_device_t,
						    cdev);
	int rc = -ENODEV;

	sms_info("entering, device index = %d", dev->device_index);
	if (dev->coredev) {
		struct smsclient_params_t params;
		params.initial_id = dev->device_index ?
		    dev->device_index : SMS_HOST_LIB;
		params.data_type = dev->device_index ? MSG_SMS_DAB_CHANNEL : 0;
		params.onresponse_handler = smschar_onresponse;
		params.onremove_handler = smschar_onremove;
		params.context = dev;

		rc = smscore_register_client(dev->coredev, &params,
					     &dev->smsclient);
		if (!rc)
			file->private_data = dev;
		dev->cancel_waitq = 0;
		g_pnp_status_changed = 1;
	}

	if (rc)
		sms_err("exiting, rc = %d", rc);

	return rc;
}
int smsnet_register(void)
{
	int rc;

	INIT_LIST_HEAD(&g_smsnet_clients);
	kmutex_init(&g_smsnet_clientslock);

	memset(&g_smsnet_stats, 0, sizeof(g_smsnet_stats));

	g_smsnet_device = alloc_netdev(0, "sms", smsnet_setup_device);
	if (!g_smsnet_device) {
		sms_err("alloc_netdev() failed");
		return -ENOMEM;
	}

	rc = register_netdev(g_smsnet_device);
	if (rc < 0) {
		sms_err("register_netdev() failed %d\n", rc);
		free_netdev(g_smsnet_device);
		return rc;
	}

	rc = smscore_register_hotplug(smsnet_hotplug);
	sms_info("exit - rc %d", rc);

	return rc;
}
Beispiel #7
0
void
action_output(const char *fmt, ...)
{
	va_list args;

	va_start(args, fmt);
	(void) vsnprintf(vmsgbuf, sizeof(vmsgbuf), fmt, args);
	va_end(args);
	if (sms_redirect()) {
		sms_info("%s", vmsgbuf);
		return;
	} else {
#if !defined(WC3270) /*[*/
		FILE *aout;
#endif /*]*/

#if defined(C3270) /*[*/
		any_error_output = True;
		screen_suspend();
# if defined(WC3270) /*[*/
		pager_output(vmsgbuf);
# else /*][*/
		aout = start_pager();
# endif /*]*/
#else /*][*/
		aout = stdout;
#endif /*]*/
#if !defined(WC3270) /*[*/
		(void) fprintf(aout, "%s\n", vmsgbuf);
#endif /*]*/
		macro_output = True;
	}
}
static int smsnet_open(struct net_device *dev)
{
	g_smsnet_inuse++;

	netif_start_queue(dev);
	sms_info("smsnet in use %d", g_smsnet_inuse);
	return 0;
}
void smschar_unregister(void)
{
	dev_t devno = MKDEV(smschar_major, smschar_minor);

	unregister_chrdev_region(devno, SMSCHAR_NR_DEVS);
	smscore_unregister_hotplug(smschar_hotplug);
	sms_info("unregistered");
}
Beispiel #10
0
/**
 * unregisters client associated with the node
 *
 * @param inode Inode concerned.
 * @param file File concerned.
 *
 */
static int smschar_release(struct inode *inode, struct file *file)
{
	smschar_unregister_client(file->private_data);

	sms_info("exiting");

	return 0;
}
/**
 * unregisters client associated with the node
 *
 * @param inode Inode concerned.
 * @param file File concerned.
 *
 */
static int smschar_release(struct inode *inode, struct file *file)
{
	struct smschar_device_t *dev = file->private_data;
	sms_info("entering, %d\n", g_open_count);

	smschar_unregister_client(file->private_data);

	if(!(--g_open_count)&& (g_open_first==0))
	{
		smscore_reset_device_drvs(dev->coredev);
		smsspi_off();
		g_open_first=0;
		sms_info("Released last time");
	}

	sms_info("exiting");
	return 0;
}
static int smsspi_preload(void *context)
{
    struct _smsspi_txmsg msg;
    struct _spi_device_st *spi_device = (struct _spi_device_st *) context;
    struct _Msg Msg = {
        {
            MSG_SMS_SPI_INT_LINE_SET_REQ, 0, HIF_TASK,
            sizeof(struct _Msg), 0
        }, {
            0, intr_pin, 200
        }
    };
    int rc;

    prepareForFWDnl(spi_device->phy_dev);
    sms_info("Sending SPI init sequence\n");
    msg.buffer = smsspi_startup;
    msg.size = sizeof(smsspi_startup);
    msg.alignment = 4;
    msg.add_preamble = 0;
    msg.prewrite = NULL;	/* smsspiphy_reduce_clock; */
    msg.postwrite = NULL;   /* smsspiphy_restore_clock; */

    rc = smsspi_queue_message_and_wait(context, &msg);
    if (rc < 0) {
        sms_err("smsspi_queue_message_and_wait error, rc = %d\n", rc);
        return rc;
    }

    sms_info("Sending SPI Set Interrupt command sequence\n");
    msg.buffer = &Msg;
    msg.size = sizeof(Msg);
    msg.alignment = SPI_PACKET_SIZE;
    msg.add_preamble = 1;

    rc = smsspi_queue_message_and_wait(context, &msg);
    if (rc < 0) {
        sms_err("set interrupt line failed, rc = %d\n", rc);
        return rc;
    }

    return rc;
}
Beispiel #13
0
static int smsi2c_sendrequest(void *context, void *buffer, size_t size)
{
	int ret;
	struct smsi2c_device *smsdev = (struct smsi2c_device *)context;
	
	if (!smsdev)
	{
		sms_err("smsi2c_sendrequest smsdev NULL!!\n");
		return -ENODEV;
	}
#if 0		
	sms_info("Writing message to I2C, size = %d bytes.\n", size);
	sms_info("msg hdr: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x.\n",
		((u8 *) buffer)[0], ((u8 *) buffer)[1], ((u8 *) buffer)[2],
		((u8 *) buffer)[3], ((u8 *) buffer)[4], ((u8 *) buffer)[5],
		((u8 *) buffer)[6], ((u8 *) buffer)[7]);
#endif
	//ret = i2c_master_send(smsdev->client, buffer, (int)size); 
	ret = i2c_master_normal_send(smsdev->client, buffer, (int)size, I2C_SCL_TATE); //using 400KHz clk
	sms_debug("i2c_master_send returned %d", ret);
	return ret;
}
Beispiel #14
0
void
action_output(const char *fmt, ...)
{
    va_list args;
    char *s;

    va_start(args, fmt);
    s = xs_vbuffer(fmt, args);
    va_end(args);
    if (sms_redirect()) {
	sms_info("%s", s);
    } else {
	if (!glue_gui_output(s)) {
	    (void) printf("%s\n", s);
	}
	any_error_output = true;
	macro_output = true;
    }
    Free(s);
}
void smsnet_unregister(void)
{
	if (g_smsnet_device) {
		unregister_netdev(g_smsnet_device);
		free_netdev(g_smsnet_device);

		g_smsnet_device = NULL;
	}

	smscore_unregister_hotplug(smsnet_hotplug);

	kmutex_lock(&g_smsnet_clientslock);

	while (!list_empty(&g_smsnet_clients))
		smsnet_unregister_client((struct smsnet_client_t *)
					 g_smsnet_clients.next);

	kmutex_unlock(&g_smsnet_clientslock);

	sms_info("exit");
}
int smsnet_hotplug(struct smscore_device_t *coredev, struct device *device,
		   int arrival)
{
	struct smsclient_params_t params;
	struct smsnet_client_t *client;
	int rc;

	/* device removal handled by onremove callback */
	if (!arrival)
		return 0;

	client = kzalloc(sizeof(struct smsnet_client_t), GFP_KERNEL);
	if (!client) {
		sms_err("kmalloc() failed");
		return -ENOMEM;
	}

	params.initial_id = 1;
	params.data_type = MSG_SMS_DATA_MSG;
	params.onresponse_handler = smsnet_onresponse;
	params.onremove_handler = smsnet_onremove;
	params.context = client;

	rc = smscore_register_client(coredev, &params, &client->smsclient);
	if (rc < 0) {
		sms_err("smscore_register_client() failed %d", rc);
		kfree(client);
		return rc;
	}

	client->coredev = coredev;
	kmutex_lock(&g_smsnet_clientslock);
	list_add(&client->entry, &g_smsnet_clients);
	kmutex_unlock(&g_smsnet_clientslock);
	sms_info("success");
	return 0;
}
Beispiel #17
0
int smschar_register(void)
{
	dev_t devno = MKDEV(smschar_major, smschar_minor);
	int rc;

	sms_info("registering device major=%d minor=%d", smschar_major,
		 smschar_minor);
	if (smschar_major) {
		rc = register_chrdev_region(devno, SMSCHAR_NR_DEVS, "smschar");
	} else {
		rc = alloc_chrdev_region(&devno, smschar_minor,
					 SMSCHAR_NR_DEVS, "smschar");
		smschar_major = MAJOR(devno);
	}

	if (rc < 0) {
		sms_warn("smschar: can't get major %d", smschar_major);
		return rc;
	}
	init_waitqueue_head(&g_pnp_event);
	kmutex_init(&g_smschar_pollwait_lock);

	return smscore_register_hotplug(smschar_hotplug);
}
Beispiel #18
0
static int smschar_ioctl(struct inode *inode, struct file *file,
			 unsigned int cmd, unsigned long arg)
{
	struct smschar_device_t *dev = file->private_data;
	void __user *up = (void __user *)arg;

	if (!dev->coredev || !dev->smsclient) {
		sms_err("no client\n");
		return -ENODEV;
	}

	switch (cmd) {
	case SMSCHAR_SET_DEVICE_MODE:
		return smscore_set_device_mode(dev->coredev, (int)arg);

	case SMSCHAR_GET_DEVICE_MODE:
		{
			if (put_user(smscore_get_device_mode(dev->coredev),
				     (int *)up))
				return -EFAULT;
			break;
		}
	case SMSCHAR_IS_DEVICE_PNP_EVENT:
		{
			sms_info("Waiting for PnP event.\n");
			wait_event_interruptible(g_pnp_event,
						 !g_pnp_status_changed);
			g_pnp_status_changed = 0;
			sms_info("PnP Event %d.\n", g_smschar_inuse);
			if (put_user(g_smschar_inuse, (int *)up))
				return -EFAULT;
			break;
		}
	case SMSCHAR_GET_BUFFER_SIZE:
		{
			if (put_user
			    (smscore_get_common_buffer_size(dev->coredev),
			     (int *)up))
				return -EFAULT;

			break;
		}

	case SMSCHAR_WAIT_GET_BUFFER:
		{
			struct smschar_buffer_t touser;
			int rc;

			rc = smschar_wait_get_buffer(dev, &touser);
			if (rc < 0)
				return rc;

			if (copy_to_user(up, &touser,
					 sizeof(struct smschar_buffer_t)))
				return -EFAULT;

			break;
		}
	case SMSCHAR_CANCEL_WAIT_BUFFER:
		{
			dev->cancel_waitq = 1;
			wake_up_interruptible(&dev->waitq);
			break;
		}
	case SMSCHAR_CANCEL_POLL:
		{
			/*obsollete*/
			break;		
		}
	case SMSCHAR_GET_FW_FILE_NAME:
		{
			if (!up)
				return -EINVAL;
			return smschar_get_fw_filename(dev,
				       (struct smschar_get_fw_filename_ioctl_t*)up);
		}
	case SMSCHAR_SEND_FW_FILE:
		{
			if (!up)
				return -EINVAL;
			return smschar_send_fw_file(dev,
					(struct smschar_send_fw_file_ioctl_t*)up);
		}

	default:
		return -ENOIOCTLCMD;
	}

	return 0;
}
static int smsnet_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
	sms_info("enter");
	dev_kfree_skb(skb);
	return 0;
}
int smsspi_register(void)
{
    struct smsdevice_params_t params;
    int ret;
    struct _spi_device_st *spi_device;
    struct _spi_dev_cb_st common_cb;

    sms_info("entering \n");

    spi_device =
        kmalloc(sizeof(struct _spi_device_st), GFP_KERNEL);
    spi_dev = spi_device;

    INIT_LIST_HEAD(&spi_device->txqueue);

    ret = platform_device_register(&smsspi_device);
    if (ret < 0) {
        PERROR("platform_device_register failed\n");
        return ret;
    }

    spi_device->txbuf =
        dma_alloc_coherent(NULL, TX_BUFFER_SIZE,
                           &spi_device->txbuf_phy_addr,
                           GFP_KERNEL | GFP_DMA);
    if (!spi_device->txbuf) {
        printk(KERN_INFO "%s dma_alloc_coherent(...) failed\n",
               __func__);
        ret = -ENOMEM;
        goto txbuf_error;
    }

    spi_device->phy_dev =
        smsspiphy_init(NULL, smsspi_int_handler, spi_device);
    if (spi_device->phy_dev == 0) {
        printk(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__);
        goto phy_error;
    }

    common_cb.allocate_rx_buf = allocate_rx_buf;
    common_cb.free_rx_buf = free_rx_buf;
    common_cb.msg_found_cb = msg_found;
    common_cb.transfer_data_cb = smsspibus_xfer;

    ret =
        smsspicommon_init(&spi_device->dev, spi_device, spi_device->phy_dev,
                          &common_cb);
    if (ret) {
        printk(KERN_INFO "%s smsspiphy_init(...) failed\n", __func__);
        goto common_error;
    }

    /* register in smscore */
    memset(&params, 0, sizeof(params));
    params.context = spi_device;
    params.device = &smsspi_device.dev;
    params.buffer_size = RX_BUFFER_SIZE;
    params.num_buffers = NUM_RX_BUFFERS;
    params.flags = SMS_DEVICE_NOT_READY;
    params.sendrequest_handler = smsspi_write;
    strcpy(params.devpath, "spi");
    params.device_type = default_type;

    if (0) {
        /* device family */
        /* params.setmode_handler = smsspi_setmode; */
    } else {
        params.flags =
            SMS_DEVICE_FAMILY2 | SMS_DEVICE_NOT_READY;
        params.preload_handler = smsspi_preload;
        params.postload_handler = smsspi_postload;
    }

    ret = smscore_register_device(&params, &spi_device->coredev);
    if (ret < 0) {
        printk(KERN_INFO "%s smscore_register_device(...) failed\n",
               __func__);
        goto reg_device_error;
    }

    ret = smscore_start_device(spi_device->coredev);
    if (ret < 0) {
        printk(KERN_INFO "%s smscore_start_device(...) failed\n",
               __func__);
        goto start_device_error;
    }

    sms_info("exiting\n");
    return 0;

start_device_error:
    smscore_unregister_device(spi_device->coredev);

reg_device_error:

common_error:
    smsspiphy_deinit(spi_device->phy_dev);

phy_error:
    dma_free_coherent(NULL, TX_BUFFER_SIZE, spi_device->txbuf,
                      spi_device->txbuf_phy_addr);

txbuf_error:
    platform_device_unregister(&smsspi_device);

    sms_info("exiting error %d\n", ret);

    return ret;
}
static int smsdvb_hotplug(struct smscore_device_t *coredev,
			  struct device *device, int arrival)
{
	struct smsclient_params_t params;
	struct smsdvb_client_t *client;
	int rc;

	/* device removal handled by onremove callback */
	if (!arrival)
		return 0;

	if (smscore_get_device_mode(coredev) != 4) {
		sms_err("SMS Device mode is not set for "
			"DVB operation.");
		return 0;
	}

	client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
	if (!client) {
		sms_err("kmalloc() failed");
		return -ENOMEM;
	}

	/* register dvb adapter */
	rc = dvb_register_adapter(&client->adapter,
				  sms_get_board(
					smscore_get_board_id(coredev))->name,
				  THIS_MODULE, device, adapter_nr);
	if (rc < 0) {
		sms_err("dvb_register_adapter() failed %d", rc);
		goto adapter_error;
	}

	/* init dvb demux */
	client->demux.dmx.capabilities = DMX_TS_FILTERING;
	client->demux.filternum = 32; /* todo: nova ??? */
	client->demux.feednum = 32;
	client->demux.start_feed = smsdvb_start_feed;
	client->demux.stop_feed = smsdvb_stop_feed;

	rc = dvb_dmx_init(&client->demux);
	if (rc < 0) {
		sms_err("dvb_dmx_init failed %d", rc);
		goto dvbdmx_error;
	}

	/* init dmxdev */
	client->dmxdev.filternum = 32;
	client->dmxdev.demux = &client->demux.dmx;
	client->dmxdev.capabilities = 0;

	rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
	if (rc < 0) {
		sms_err("dvb_dmxdev_init failed %d", rc);
		goto dmxdev_error;
	}

	/* init and register frontend */
	memcpy(&client->frontend.ops, &smsdvb_fe_ops,
	       sizeof(struct dvb_frontend_ops));

	rc = dvb_register_frontend(&client->adapter, &client->frontend);
	if (rc < 0) {
		sms_err("frontend registration failed %d", rc);
		goto frontend_error;
	}

	params.initial_id = 1;
	params.data_type = MSG_SMS_DVBT_BDA_DATA;
	params.onresponse_handler = smsdvb_onresponse;
	params.onremove_handler = smsdvb_onremove;
	params.context = client;

	rc = smscore_register_client(coredev, &params, &client->smsclient);
	if (rc < 0) {
		sms_err("smscore_register_client() failed %d", rc);
		goto client_error;
	}

	client->coredev = coredev;

	init_completion(&client->tune_done);
	init_completion(&client->stat_done);

	kmutex_lock(&g_smsdvb_clientslock);

	list_add(&client->entry, &g_smsdvb_clients);

	kmutex_unlock(&g_smsdvb_clientslock);

	sms_info("success");

	sms_board_setup(coredev);

	return 0;

client_error:
	dvb_unregister_frontend(&client->frontend);

frontend_error:
	dvb_dmxdev_release(&client->dmxdev);

dmxdev_error:
	dvb_dmx_release(&client->demux);

dvbdmx_error:
	dvb_unregister_adapter(&client->adapter);

adapter_error:
	kfree(client);
	return rc;
}
Beispiel #22
0
void *smsspiphy_init(void *context,
	void (*smsspi_interruptHandler) (void *), void *intr_context)
{
  struct spiphy_dev_s *spiphy_dev;
  int ret;

  smsmdtv_dev = 0;

	spiphy_dev = kmalloc(sizeof(struct spiphy_dev_s), GFP_KERNEL);
	if (spiphy_dev == 0) {
		sms_err("malloc for spi_dev failed");
		goto err_malloc;
	}
	spiphy_dev->interruptHandler = smsspi_interruptHandler;
	spiphy_dev->intr_context     = intr_context;

  ret = spi_register_driver(&smsmdtv_driver);

	if (ret < 0 || smsmdtv_dev == 0) {
		sms_info("Cann't get SPI device\n");
		goto err_register;
  }

	spiphy_dev->dev      = smsmdtv_dev;


  /*spi_loop_test(slave);*/

  spiphy_dev->irq = gpio_to_irq(SMS_IRQ_GPIO);

  set_irq_type(spiphy_dev->irq, IRQ_TYPE_EDGE_RISING);
	ret = request_irq(spiphy_dev->irq, spibus_interrupt, \
		IRQF_TRIGGER_RISING|IRQF_DISABLED, "smsmdtv", spiphy_dev);

	if (ret < 0) {
		sms_info("Unable to request irq %d", ret);
		goto err_irq;
	}

	/* interrupt disable */
	disable_irq(gpio_to_irq(SMS_IRQ_GPIO));
	smsmdtv_int_enable_flag = INTERRUPT_DISABLE;
	printk(KERN_INFO "smsspiphy_init(): disable_irq\n");

	spiphy_dev->txpad = dma_alloc_coherent(NULL, TX_BUFFER_SIZE,
			&spiphy_dev->txpad_phy_addr,
			GFP_KERNEL|GFP_DMA);
	if (!spiphy_dev->txpad) {
    ret = -ENOMEM;
    goto err_txpad;
	}
  memset(spiphy_dev->txpad, 0xFF, TX_BUFFER_SIZE);


	PDEBUG("exiting\n");
	return spiphy_dev;

err_txpad:
  free_irq(spiphy_dev->irq, spiphy_dev);
err_irq:
  gpio_free(SMS_IRQ_GPIO);
  spi_unregister_driver(&smsmdtv_driver);
err_register:
  kfree(spiphy_dev);
err_malloc:
	return 0;
}
Beispiel #23
0
static int smsdvb_isdbt_set_frontend(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	struct smsdvb_client_t *client =
		container_of(fe, struct smsdvb_client_t, frontend);
	int board_id = smscore_get_board_id(client->coredev);
	struct sms_board *board = sms_get_board(board_id);
	enum sms_device_type_st type = board->type;
	int ret;

	struct {
		struct sms_msg_hdr	msg;
		u32		Data[4];
	} msg;

	fe->dtv_property_cache.delivery_system = SYS_ISDBT;

	msg.msg.msg_src_id  = DVBT_BDA_CONTROL_MSG_ID;
	msg.msg.msg_dst_id  = HIF_TASK;
	msg.msg.msg_flags  = 0;
	msg.msg.msg_type   = MSG_SMS_ISDBT_TUNE_REQ;
	msg.msg.msg_length = sizeof(msg);

	if (c->isdbt_sb_segment_idx == -1)
		c->isdbt_sb_segment_idx = 0;

	if (!c->isdbt_layer_enabled)
		c->isdbt_layer_enabled = 7;

	msg.Data[0] = c->frequency;
	msg.Data[1] = BW_ISDBT_1SEG;
	msg.Data[2] = 12000000;
	msg.Data[3] = c->isdbt_sb_segment_idx;

	if (c->isdbt_partial_reception) {
		if ((type == SMS_PELE || type == SMS_RIO) &&
		    c->isdbt_sb_segment_count > 3)
			msg.Data[1] = BW_ISDBT_13SEG;
		else if (c->isdbt_sb_segment_count > 1)
			msg.Data[1] = BW_ISDBT_3SEG;
	} else if (type == SMS_PELE || type == SMS_RIO)
		msg.Data[1] = BW_ISDBT_13SEG;

	c->bandwidth_hz = 6000000;

	sms_info("%s: freq %d segwidth %d segindex %d", __func__,
		 c->frequency, c->isdbt_sb_segment_count,
		 c->isdbt_sb_segment_idx);

	/* Disable LNA, if any. An error is returned if no LNA is present */
	ret = sms_board_lna_control(client->coredev, 0);
	if (ret == 0) {
		fe_status_t status;

		/* tune with LNA off at first */
		ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg),
						  &client->tune_done);

		smsdvb_read_status(fe, &status);

		if (status & FE_HAS_LOCK)
			return ret;

		/* previous tune didn't lock - enable LNA and tune again */
		sms_board_lna_control(client->coredev, 1);
	}
	return smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg),
					   &client->tune_done);
}
Beispiel #24
0
static int smsdvb_dvbt_set_frontend(struct dvb_frontend *fe)
{
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	struct smsdvb_client_t *client =
		container_of(fe, struct smsdvb_client_t, frontend);

	struct {
		struct sms_msg_hdr	msg;
		u32		Data[3];
	} msg;

	int ret;

	client->fe_status = 0;
	client->event_fe_state = -1;
	client->event_unc_state = -1;
	fe->dtv_property_cache.delivery_system = SYS_DVBT;

	msg.msg.msg_src_id = DVBT_BDA_CONTROL_MSG_ID;
	msg.msg.msg_dst_id = HIF_TASK;
	msg.msg.msg_flags = 0;
	msg.msg.msg_type = MSG_SMS_RF_TUNE_REQ;
	msg.msg.msg_length = sizeof(msg);
	msg.Data[0] = c->frequency;
	msg.Data[2] = 12000000;

	sms_info("%s: freq %d band %d", __func__, c->frequency,
		 c->bandwidth_hz);

	switch (c->bandwidth_hz / 1000000) {
	case 8:
		msg.Data[1] = BW_8_MHZ;
		break;
	case 7:
		msg.Data[1] = BW_7_MHZ;
		break;
	case 6:
		msg.Data[1] = BW_6_MHZ;
		break;
	case 0:
		return -EOPNOTSUPP;
	default:
		return -EINVAL;
	}
	/* Disable LNA, if any. An error is returned if no LNA is present */
	ret = sms_board_lna_control(client->coredev, 0);
	if (ret == 0) {
		fe_status_t status;

		/* tune with LNA off at first */
		ret = smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg),
						  &client->tune_done);

		smsdvb_read_status(fe, &status);

		if (status & FE_HAS_LOCK)
			return ret;

		/* previous tune didn't lock - enable LNA and tune again */
		sms_board_lna_control(client->coredev, 1);
	}

	return smsdvb_sendrequest_and_wait(client, &msg, sizeof(msg),
					   &client->tune_done);
}
Beispiel #25
0
static int smsdvb_hotplug(struct smscore_device_t *coredev,
			  struct device *device, int arrival)
{
	struct smsclient_params_t params;
	struct smsdvb_client_t *client;
	int rc;
	int mode = smscore_get_device_mode(coredev);
	//mode = 6;
	/* device removal handled by onremove callback */
	if (!arrival)
		return 0;

	if ( (mode != DEVICE_MODE_DVBT_BDA) &&
	     (mode != DEVICE_MODE_ISDBT_BDA) ) {
		sms_err("SMS Device mode is not set for "
			"DVB operation.");
		return 0;
	}

	client = kzalloc(sizeof(struct smsdvb_client_t), GFP_KERNEL);
	if (!client) {
		sms_err("kmalloc() failed");
		return -ENOMEM;
	}

	/* register dvb adapter */
#ifdef SMS_DVB_OLD_DVB_REGISTER_ADAPTER
	rc = dvb_register_adapter(&client->adapter,
				  sms_get_board(smscore_get_board_id(coredev))->
				  name, THIS_MODULE, device);
#else
	rc = dvb_register_adapter(&client->adapter,
				  sms_get_board(smscore_get_board_id(coredev))->
				  name, THIS_MODULE, device, adapter_nr);
#endif
	if (rc < 0) {
		sms_err("dvb_register_adapter() failed %d", rc);
		goto adapter_error;
	}

	/* init dvb demux */
	client->demux.dmx.capabilities = DMX_TS_FILTERING;
	client->demux.filternum = 32; /* todo: nova ??? */
	client->demux.feednum = 32;
	client->demux.start_feed = smsdvb_start_feed;
	client->demux.stop_feed = smsdvb_stop_feed;

	rc = dvb_dmx_init(&client->demux);
	if (rc < 0) {
		sms_err("dvb_dmx_init failed %d", rc);
		goto dvbdmx_error;
	}

	/* init dmxdev */
	client->dmxdev.filternum = 32;
	client->dmxdev.demux = &client->demux.dmx;
	client->dmxdev.capabilities = 0;

	rc = dvb_dmxdev_init(&client->dmxdev, &client->adapter);
	if (rc < 0) {
		sms_err("dvb_dmxdev_init failed %d", rc);
		goto dmxdev_error;
	}
	//add by luis
	printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__);
	//add by luis

	/* init and register frontend */
	memcpy(&client->frontend.ops, &smsdvb_fe_ops,
	       sizeof(struct dvb_frontend_ops));
	//add by luis
	printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__);
	//add by luis

	rc = dvb_register_frontend(&client->adapter, &client->frontend);
	if (rc < 0) {
		sms_err("frontend registration failed %d", rc);
		goto frontend_error;
	}

	params.initial_id = 1;
	params.data_type = MSG_SMS_DVBT_BDA_DATA;
	params.onresponse_handler = smsdvb_onresponse;
	params.onremove_handler = smsdvb_onremove;
	params.context = client;
	//add by luis
	printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__);
	//add by luis

	rc = smscore_register_client(coredev, &params, &client->smsclient);
	if (rc < 0) {
		sms_err("smscore_register_client() failed %d", rc);
		goto client_error;
	}

	client->coredev = coredev;

	init_completion(&client->tune_done);
	init_completion(&client->get_stats_done);

	kmutex_lock(&g_smsdvb_clientslock);

	list_add(&client->entry, &g_smsdvb_clients);

	kmutex_unlock(&g_smsdvb_clientslock);

	client->event_fe_state = -1;
	client->event_unc_state = -1;
	sms_board_dvb3_event(client, DVB3_EVENT_HOTPLUG);
	//add by luis
	printk("debug: %s, %d, %s>>>>>>>>>>>>>>>>>>>>\n", __FILE__, __LINE__, __FUNCTION__);
	//add by luis

	sms_info("success");
	return 0;

client_error:
	dvb_unregister_frontend(&client->frontend);

frontend_error:
	dvb_dmxdev_release(&client->dmxdev);

dmxdev_error:
	dvb_dmx_release(&client->demux);

dvbdmx_error:
	dvb_unregister_adapter(&client->adapter);

adapter_error:
	kfree(client);
	return rc;
}
Beispiel #26
0
static void smsi2c_worker_thread(void *args) 
{
	struct smscore_buffer_t *cb;
	struct SmsMsgHdr_S *phdr;
	u16 len;
	int ret;
	u8 local_buf[100];
	sms_debug("Worker thread is running.\n");
	if (!g_smsi2c_device->coredev)
	{
		sms_debug("Using local buffer\n");
		cb = NULL;
		phdr = (struct SmsMsgHdr_S *)local_buf;
	}
	else
	{
		sms_debug("Using core buffer\n");
		cb = smscore_getbuffer(g_smsi2c_device->coredev);
		if (!cb) {
			sms_err("Unable to allocate data buffer!\n");
			goto exit;
		}
		phdr = (struct SmsMsgHdr_S *)cb->p;
	}	
	sms_debug("Recieve the message header.....\n");
	memset(phdr, 0, (int)sizeof(struct SmsMsgHdr_S));
	sms_debug("buf before: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
		((u8*)phdr)[0], ((u8*)phdr)[1], ((u8*)phdr)[2], ((u8*)phdr)[3], 
		((u8*)phdr)[4], ((u8*)phdr)[5], ((u8*)phdr)[6], ((u8*)phdr)[7]);
#if 0
	ret = i2c_master_recv(g_smsi2c_device->client, 
							(void *)phdr, 
							(int)sizeof(struct SmsMsgHdr_S));
#else
	ret = i2c_master_normal_recv(g_smsi2c_device->client, 
							(void *)phdr, 
							(int)sizeof(struct SmsMsgHdr_S), I2C_SCL_TATE);
	
#endif
	if (ret < 0) {
		if ((void*)phdr != (void*)local_buf)
			smscore_putbuffer(g_smsi2c_device->coredev, cb);
		sms_err("Unable to read sms header! ret=%d\n", ret);
		goto exit;
	}
#if 0	
	sms_debug("hdr: type=%d, src=%d, dst=%d, len=%d, flag=0x%x\n", 
		phdr->msgType, phdr->msgSrcId, phdr->msgDstId, phdr->msgLength, phdr->msgFlags);
	sms_debug("buf: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
		((u8*)phdr)[0], ((u8*)phdr)[1], ((u8*)phdr)[2], ((u8*)phdr)[3], 
		((u8*)phdr)[4], ((u8*)phdr)[5], ((u8*)phdr)[6], ((u8*)phdr)[7]);
	sms_debug("Recieve the rest of the message.....\n");
#endif	
	len = phdr->msgLength;
	
	if (len > sizeof(struct SmsMsgHdr_S))
	{
#if 0
		ret = i2c_master_recv(g_smsi2c_device->client, 
								(u8*)(phdr+1), 
								len - (int)sizeof(struct SmsMsgHdr_S));
#else
		ret = i2c_master_normal_recv(g_smsi2c_device->client, 
								(u8*)(phdr+1), 
								len - (int)sizeof(struct SmsMsgHdr_S), I2C_SCL_TATE);
	
#endif
		//sms_debug("recv of data returned %d", ret);
		if (ret < 0) {
			if ((void*)phdr != (void*)local_buf)
				smscore_putbuffer(g_smsi2c_device->coredev, cb);
			sms_err("Unable to read sms payload!\n");
			goto exit;
		}
		sms_debug("data: 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x, 0x%x",
			((u8*)(phdr+1))[0], ((u8*)(phdr+1))[1], ((u8*)(phdr+1))[2], ((u8*)(phdr+1))[3], 
			((u8*)(phdr+1))[4], ((u8*)(phdr+1))[5], ((u8*)(phdr+1))[6], ((u8*)(phdr+1))[7]);
	}
	if ((phdr->msgType == MSG_SMS_GET_VERSION_EX_RES) && ((void*)phdr == (void*)local_buf))
	{ /*This was an internal command, so we won't send it out*/
		g_smsi2c_device->chip_model = *((u16*)(phdr+1));
		sms_info("chip model=0x%x\n", g_smsi2c_device->chip_model);
		g_smsi2c_device->chip_metal = ((u8*)(phdr+1))[3];
		sms_info("chip step=0x%x\n", g_smsi2c_device->chip_metal);
		g_smsi2c_device->wait_for_version_resp = 0;
		sms_info("complete get version\n");
		complete(&g_smsi2c_device->version_ex_done);
		sms_info("done.");
		return;
	}
#ifdef I2C_TS_ENABLE
	{
		if (MSG_SMS_INIT_DEVICE_RES == phdr->msgType) {
			ret = smsi2c_ts_enable(g_smsi2c_device);
			sms_debug("smsi2c_ts_enable.......\n");
		}
	}
#endif
	sms_debug("Message recieved. Sending to callback.....\n");	
	if (((void*)phdr != (void*)local_buf))
	{
		sms_debug("Ext buf.....\n");	
		cb->offset = 0;
		cb->size = len;
		if	(g_smsi2c_device->coredev)
		{
			smscore_onresponse(g_smsi2c_device->coredev, cb);
		}
	}
exit:
	return;
}
Beispiel #27
0
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
{
	struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
	struct sms_msg_hdr *phdr = (struct sms_msg_hdr *) (((u8 *) cb->p)
			+ cb->offset);
	void *p = phdr + 1;
	struct dvb_frontend *fe = &client->frontend;
	struct dtv_frontend_properties *c = &fe->dtv_property_cache;
	bool is_status_update = false;

	switch (phdr->msg_type) {
	case MSG_SMS_DVBT_BDA_DATA:
		/*
		 * Only feed data to dvb demux if are there any feed listening
		 * to it and if the device has tuned
		 */
		if (client->feed_users && client->has_tuned)
			dvb_dmx_swfilter(&client->demux, p,
					 cb->size - sizeof(struct sms_msg_hdr));
		break;

	case MSG_SMS_RF_TUNE_RES:
	case MSG_SMS_ISDBT_TUNE_RES:
		complete(&client->tune_done);
		break;

	case MSG_SMS_SIGNAL_DETECTED_IND:
		client->fe_status = FE_HAS_SIGNAL  | FE_HAS_CARRIER |
				    FE_HAS_VITERBI | FE_HAS_SYNC    |
				    FE_HAS_LOCK;

		is_status_update = true;
		break;

	case MSG_SMS_NO_SIGNAL_IND:
		client->fe_status = 0;

		is_status_update = true;
		break;

	case MSG_SMS_TRANSMISSION_IND:
		smsdvb_update_tx_params(client, p);

		is_status_update = true;
		break;

	case MSG_SMS_HO_PER_SLICES_IND:
		smsdvb_update_per_slices(client, p);

		is_status_update = true;
		break;

	case MSG_SMS_GET_STATISTICS_RES:
		switch (smscore_get_device_mode(client->coredev)) {
		case DEVICE_MODE_ISDBT:
		case DEVICE_MODE_ISDBT_BDA:
			smsdvb_update_isdbt_stats(client, p);
			break;
		default:
			/* Skip sms_msg_statistics_info:request_result field */
			smsdvb_update_dvb_stats(client, p + sizeof(u32));
		}

		is_status_update = true;
		break;

	/* Only for ISDB-T */
	case MSG_SMS_GET_STATISTICS_EX_RES:
		/* Skip sms_msg_statistics_info:request_result field? */
		smsdvb_update_isdbt_stats_ex(client, p + sizeof(u32));
		is_status_update = true;
		break;
	default:
		sms_info("message not handled");
	}
	smscore_putbuffer(client->coredev, cb);

	if (is_status_update) {
		if (client->fe_status & FE_HAS_LOCK) {
			sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
			if (client->last_per == c->block_error.stat[0].uvalue)
				sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
			else
				sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR);
			client->has_tuned = true;
		} else {
			smsdvb_stats_not_ready(fe);
			client->has_tuned = false;
			sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
		}
		complete(&client->stats_done);
	}

	return 0;
}
Beispiel #28
0
static int smsdvb_onresponse(void *context, struct smscore_buffer_t *cb)
{
	struct smsdvb_client_t *client = (struct smsdvb_client_t *) context;
	struct SmsMsgHdr_ST *phdr = (struct SmsMsgHdr_ST *) (((u8 *) cb->p)
			+ cb->offset);
	u32 *pMsgData = (u32 *) (phdr + 1);
	/*u32 MsgDataLen = phdr->msgLength - sizeof(struct SmsMsgHdr_ST);*/
	bool is_status_update = false;

	smsendian_handle_rx_message((struct SmsMsgData_ST *) phdr);

	switch (phdr->msgType) {
	case MSG_SMS_DVBT_BDA_DATA:
		dvb_dmx_swfilter(&client->demux, (u8 *) (phdr + 1), cb->size
				- sizeof(struct SmsMsgHdr_ST));
		break;

	case MSG_SMS_ISDBT_TUNE_RES:
		sms_info("MSG_SMS_ISDBT_TUNE_RES");	
	case MSG_SMS_RF_TUNE_RES:
		complete(&client->tune_done);
		break;

	case MSG_SMS_SIGNAL_DETECTED_IND:
		sms_info("MSG_SMS_SIGNAL_DETECTED_IND");
		client->sms_stat_dvb.ReceptionData.IsDemodLocked = true;
		is_status_update = true;
		break;

	case MSG_SMS_NO_SIGNAL_IND:
		sms_info("MSG_SMS_NO_SIGNAL_IND");
		client->sms_stat_dvb.ReceptionData.IsDemodLocked = false;
		is_status_update = true;
		break;

	case MSG_SMS_TRANSMISSION_IND: {
		sms_info("MSG_SMS_TRANSMISSION_IND");

		memcpy(&client->sms_stat_dvb.TransmissionData, pMsgData,
				sizeof(struct TRANSMISSION_STATISTICS_S));

		/* Mo need to correct guard interval
		 * (as opposed to old statistics message).
		 */
		CORRECT_STAT_BANDWIDTH(client->sms_stat_dvb.TransmissionData);
		CORRECT_STAT_TRANSMISSON_MODE(
				client->sms_stat_dvb.TransmissionData);
		is_status_update = true;
		break;
	}
	case MSG_SMS_HO_PER_SLICES_IND: {
		struct RECEPTION_STATISTICS_S *pReceptionData =
				&client->sms_stat_dvb.ReceptionData;
		struct SRVM_SIGNAL_STATUS_S SignalStatusData;

		/*sms_info("MSG_SMS_HO_PER_SLICES_IND");*/
		SignalStatusData.result = pMsgData[0];
		SignalStatusData.snr = pMsgData[1];
		SignalStatusData.inBandPower = (s32) pMsgData[2];
		SignalStatusData.tsPackets = pMsgData[3];
		SignalStatusData.etsPackets = pMsgData[4];
		SignalStatusData.constellation = pMsgData[5];
		SignalStatusData.hpCode = pMsgData[6];
		SignalStatusData.tpsSrvIndLP = pMsgData[7] & 0x03;
		SignalStatusData.tpsSrvIndHP = pMsgData[8] & 0x03;
		SignalStatusData.cellId = pMsgData[9] & 0xFFFF;
		SignalStatusData.reason = pMsgData[10];
		SignalStatusData.requestId = pMsgData[11];
		pReceptionData->IsRfLocked = pMsgData[16];
		pReceptionData->IsDemodLocked = pMsgData[17];
		pReceptionData->ModemState = pMsgData[12];
		pReceptionData->SNR = pMsgData[1];
		pReceptionData->BER = pMsgData[13];
		pReceptionData->RSSI = pMsgData[14];
		CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);

		pReceptionData->InBandPwr = (s32) pMsgData[2];
		pReceptionData->CarrierOffset = (s32) pMsgData[15];
		pReceptionData->TotalTSPackets = pMsgData[3];
		pReceptionData->ErrorTSPackets = pMsgData[4];

		/* TS PER */
		if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
				> 0) {
			pReceptionData->TS_PER = (SignalStatusData.etsPackets
					* 100) / (SignalStatusData.tsPackets
					+ SignalStatusData.etsPackets);
		} else {
			pReceptionData->TS_PER = 0;
		}

		pReceptionData->BERBitCount = pMsgData[18];
		pReceptionData->BERErrorCount = pMsgData[19];

		pReceptionData->MRC_SNR = pMsgData[20];
		pReceptionData->MRC_InBandPwr = pMsgData[21];
		pReceptionData->MRC_RSSI = pMsgData[22];

		is_status_update = true;
		break;
	}

	case MSG_SMS_GET_STATISTICS_EX_RES: {
		struct RECEPTION_STATISTICS_S *pReceptionData =
				&client->sms_stat_dvb.ReceptionData;
		struct SMSHOSTLIB_STATISTICS_ISDBT_S *pStatsIsdbt;
		struct SRVM_SIGNAL_STATUS_S SignalStatusData;
		/*sms_info("MSG_SMS_GET_STATISTICS_EX_RES");*/

		pMsgData++;
		pStatsIsdbt = (struct SMSHOSTLIB_STATISTICS_ISDBT_S*)pMsgData;
/*
		sms_info("%d layers detected", pStatsIsdbt->NumOfLayers);
		sms_info("InBandPwr = %d dBm", pStatsIsdbt->InBandPwr);
		sms_info("SNR = %d dB", pStatsIsdbt->SNR);
		sms_info("RSSI = %d dBm", pStatsIsdbt->RSSI);
*/

		/* update signal status */
		SignalStatusData.snr = pStatsIsdbt->SNR;
		SignalStatusData.tsPackets = pStatsIsdbt->LayerInfo[0].TotalTSPackets;
		SignalStatusData.etsPackets = pStatsIsdbt->LayerInfo[0].ErrorTSPackets;
		SignalStatusData.constellation = pStatsIsdbt->LayerInfo[0].Constellation;
 		SignalStatusData.inBandPower = pStatsIsdbt->InBandPwr;

		/* update reception data */
		pReceptionData->IsRfLocked = pStatsIsdbt->IsRfLocked;
		pReceptionData->IsDemodLocked = pStatsIsdbt->IsDemodLocked;
		pReceptionData->ModemState = pStatsIsdbt->ModemState;
		pReceptionData->SNR = pStatsIsdbt->SNR;
		pReceptionData->BER = pStatsIsdbt->LayerInfo[0].BER;
		pReceptionData->BERErrorCount = pStatsIsdbt->LayerInfo[0].BERErrorCount;
		pReceptionData->BERBitCount = pStatsIsdbt->LayerInfo[0].BERBitCount;
		pReceptionData->RSSI = pStatsIsdbt->RSSI;
		CORRECT_STAT_RSSI(client->sms_stat_dvb.ReceptionData);
		pReceptionData->InBandPwr = pStatsIsdbt->InBandPwr;
		pReceptionData->CarrierOffset = pStatsIsdbt->CarrierOffset;
		pReceptionData->ErrorTSPackets = pStatsIsdbt->LayerInfo[0].ErrorTSPackets;
		pReceptionData->TotalTSPackets = pStatsIsdbt->LayerInfo[0].TotalTSPackets;
		 
		/* TS PER */
		if ((SignalStatusData.tsPackets + SignalStatusData.etsPackets)
				> 0) {
			pReceptionData->TS_PER = (SignalStatusData.etsPackets
					* 100) / (SignalStatusData.tsPackets
					+ SignalStatusData.etsPackets);
		} else {
			pReceptionData->TS_PER = 0;
		}

/*
		pReceptionData->MRC_SNR =
		pReceptionData->MRC_InBandPwr =
		pReceptionData->MRC_RSSI = 
*/

		client->last_sample_time = jiffies_to_msecs(jiffies);
		is_status_update = true;
		complete(&client->get_stats_done);
		break;
	}

	}
	smscore_putbuffer(client->coredev, cb);

	if (is_status_update) {
/*
		sms_info("client->fe_status = %d",client->fe_status);
		sms_info("--- TransmissionData ---");
		sms_info("    Frequency %d", client->sms_stat_dvb.TransmissionData.Frequency);
		sms_info("    Constellation %d", client->sms_stat_dvb.TransmissionData.Constellation);
		sms_info("    IsDemodLocked %d", client->sms_stat_dvb.TransmissionData.IsDemodLocked);
		sms_info("--- ReceptionData ---");
		sms_info("    IsDemodLocked %d", client->sms_stat_dvb.ReceptionData.IsDemodLocked);
		sms_info("    BER %d", client->sms_stat_dvb.ReceptionData.BER);
		sms_info("    ErrorTSPackets %d", client->sms_stat_dvb.ReceptionData.ErrorTSPackets);
		sms_info("    InBandPwr %d", client->sms_stat_dvb.ReceptionData.InBandPwr);
		sms_info("    IsRfLocked %d", client->sms_stat_dvb.ReceptionData.IsRfLocked);
		sms_info("    RSSI %d", client->sms_stat_dvb.ReceptionData.RSSI);
		sms_info("    SNR %d", client->sms_stat_dvb.ReceptionData.SNR);
*/

		if (client->sms_stat_dvb.ReceptionData.IsDemodLocked) {
			client->fe_status = FE_HAS_SIGNAL | FE_HAS_CARRIER
				| FE_HAS_VITERBI | FE_HAS_SYNC | FE_HAS_LOCK;
			sms_board_dvb3_event(client, DVB3_EVENT_FE_LOCK);
			if (client->sms_stat_dvb.ReceptionData.ErrorTSPackets == 0)
				sms_board_dvb3_event(client, DVB3_EVENT_UNC_OK);
			else
				sms_board_dvb3_event(client, DVB3_EVENT_UNC_ERR);

		} else {
			/*client->fe_status = (phdr->msgType == MSG_SMS_NO_SIGNAL_IND) ? 0 : FE_HAS_SIGNAL;*/
			client->fe_status = 0;
			sms_board_dvb3_event(client, DVB3_EVENT_FE_UNLOCK);
		}
	}

	return 0;
}