Files
TAIXIN/sdk/lib/bus/rttusb/usbhost/class/wireless.c

138 lines
4.4 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include <rtthread.h>
#include <include/rttusb_host.h>
#include "rndis.h"
#ifdef RT_USBH_WIRELESS
static struct uclass_driver wireless_driver;
static rt_err_t rt_usbh_wireless_enable(void *arg)
{
struct uhintf **intf = arg;
uhcd_t hcd = NULL;
uep_desc_t ep_desc = NULL;
struct usb_rndis *rndis = NULL;
upipe_t pipe;
rt_uint8_t ep_index;
if (intf[0] == NULL) {
return -EIO;
}
hcd = intf[0]->device->hcd;
os_printf("subclass %d, protocal %d\r\n",
intf[0]->intf_desc->bInterfaceSubClass,
intf[0]->intf_desc->bInterfaceProtocol);
// 中云信安cat1模组在iad描述符和接口描述符中不一致兼容多了一种判断
if ((intf[0]->intf_desc->bInterfaceSubClass == 1 && intf[0]->intf_desc->bInterfaceProtocol == 3) || \
(intf[0]->intf_desc->bInterfaceSubClass == 2 && intf[0]->intf_desc->bInterfaceProtocol == 255)) {
#ifdef STATIC_RNDIS_NETDEV
rndis = (struct usb_rndis *)dev_get(HG_LTE_RNDIS_DEVID);
#else
rndis = (struct usb_rndis *)os_zalloc(sizeof(struct usb_rndis));
#endif
if (rndis == NULL) {
os_printf("rndis alloc fail\r\n");
return -ENOMEM;
}
rndis->msg_buffer = (rt_uint8_t *)os_malloc(128 + USB_RX_BUFF_RESERVE_SIZE);
if (rndis->msg_buffer == NULL) {
os_printf("rndis msg buffer alloc fail\r\n");
os_free(rndis);
return -ENOMEM;
}
rndis->data_buffer = (rt_uint8_t *)os_malloc(2048 + USB_RX_BUFF_RESERVE_SIZE);
if (rndis->data_buffer == NULL) {
os_printf("rndis data buffer alloc fail\r\n");
os_free(rndis->msg_buffer);
os_free(rndis);
return -ENOMEM;
}
rndis->ts_buffer = (rt_uint8_t *)os_zalloc(2048 + USB_RX_BUFF_RESERVE_SIZE);
if(rndis->ts_buffer == NULL) {
os_printf("rndis ts_buf alloc fail\r\n");
os_free(rndis->msg_buffer);
os_free(rndis->data_buffer);
os_free(rndis);
return -ENOMEM;
}
rndis->ts_saveLength = 0;
rndis->device = intf[0]->device;
rndis->req_id = 1;
intf[0]->user_data = rndis;
for (ep_index = 0; ep_index < intf[0]->intf_desc->bNumEndpoints; ++ep_index) {
rt_usbh_get_endpoint_descriptor(intf[0]->intf_desc, ep_index, &ep_desc);
if (ep_desc == NULL) {
return RET_ERR;
}
if ((ep_desc->bmAttributes & USB_EP_ATTR_TYPE_MASK) != USB_EP_ATTR_INT)
continue;
if ((ep_desc->bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN) {
if (rt_usb_hcd_alloc_pipe(intf[0]->device->hcd, &pipe, intf[0]->device, ep_desc) != RT_EOK) {
rt_kprintf("alloc pipe failed\n");
return -RT_ERROR;
}
rt_usb_instance_add_pipe(intf[0]->device, pipe);
rndis->pipe_int = pipe;
}
}
for (ep_index = 0; ep_index < intf[1]->intf_desc->bNumEndpoints; ++ep_index) {
rt_usbh_get_endpoint_descriptor(intf[1]->intf_desc, ep_index, &ep_desc);
if (ep_desc == NULL) {
return RET_ERR;
}
if ((ep_desc->bmAttributes & USB_EP_ATTR_TYPE_MASK) != USB_EP_ATTR_BULK)
continue;
if (rt_usb_hcd_alloc_pipe(intf[0]->device->hcd, &pipe, intf[0]->device, ep_desc) != RT_EOK) {
rt_kprintf("alloc pipe failed\n");
return -RT_ERROR;
}
rt_usb_instance_add_pipe(intf[0]->device, pipe);
if ((ep_desc->bEndpointAddress & USB_DIR_MASK) == USB_DIR_IN) {
rndis->pipe_in = pipe;
} else {
rndis->pipe_out = pipe;
}
}
rt_usbh_rndis_run(rndis);
}
return RET_OK;
}
static rt_err_t rt_usbh_wireless_disable(void *arg)
{
struct uhintf *intf = arg;
struct usb_rndis *rndis = NULL;
if (intf == NULL) {
return -EIO;
}
rndis = intf->user_data;
if (rndis) {
rt_usbh_rndis_stop(rndis);
}
return RET_OK;
}
ucd_t rt_usbh_class_driver_wireless(void)
{
wireless_driver.class_code = USB_CLASS_WIRELESS;
wireless_driver.enable = rt_usbh_wireless_enable;
wireless_driver.disable = rt_usbh_wireless_disable;
return &wireless_driver;
}
#endif