📄 zd1211.c
字号:
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,19))
dev->get_wireless_stats = zd1205_iw_getstats;
#endif
#elif !defined(ZDCONF_WE_STAT_SUPPORT)
#error "Undefine ZDCONF_WE_STAT_SUPPORT"
#endif
dev->mtu = ZD1211_MTU;
dev->set_mac_address = zd1205_set_mac;
dev->tx_timeout = &zd1211_tx_timeout;
//dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
dev->flags |= IFF_MULTICAST;
//memcpy(macp->ifname, dev->name, IFNAMSIZ);
//macp->ifname[IFNAMSIZ-1] = 0;
ZEXIT(1);
return true;
}
int zd1211_alloc_all_urbs(struct zd1205_private *macp)
{
struct usb_interface *interface = macp->interface;
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
struct usb_interface_descriptor *iface_desc = &interface->altsetting[0];
#else
struct usb_host_interface *iface_desc = &interface->altsetting[0];
#endif
struct usb_endpoint_descriptor *endpoint;
struct usb_endpoint_descriptor *interrupt_in_endpoint[MAX_NUM_PORTS];
struct usb_endpoint_descriptor *interrupt_out_endpoint[MAX_NUM_PORTS];
struct usb_endpoint_descriptor *bulk_in_endpoint[MAX_NUM_PORTS];
struct usb_endpoint_descriptor *bulk_out_endpoint[MAX_NUM_PORTS];
u8 num_bulk_in = 0;
u8 num_bulk_out = 0;
u8 num_interrupt_in = 0;
u8 num_interrupt_out = 0;
int i;
/* descriptor matches, let's find the endpoints needed */
/* check out the endpoints */
//ZD1211DEBUG(2, "bNumEndpoints = %d\n", iface_desc->bNumEndpoints);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
for (i = 0; i < iface_desc->bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i];
#else
for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
endpoint = &iface_desc->endpoint[i].desc;
#endif
if ((endpoint->bEndpointAddress & 0x80) &&
((endpoint->bmAttributes & 3) == 0x02)) {
/* we found a bulk in endpoint */
bulk_in_endpoint[num_bulk_in] = endpoint;
++num_bulk_in;
macp->wMaxPacketSize = zd_le16_to_cpu(endpoint->wMaxPacketSize);
if(macp->wMaxPacketSize != 64 && macp->wMaxPacketSize!= 512)
{
printk("Something wrong. Mostly, it's a endian issue\n");
}
ZD1211DEBUG(0, "bulk in: wMaxPacketSize = %x\n", zd_le16_to_cpu(endpoint->wMaxPacketSize));
}
if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
((endpoint->bmAttributes & 3) == 0x02)) {
/* we found a bulk out endpoint */
bulk_out_endpoint[num_bulk_out] = endpoint;
++num_bulk_out;
ZD1211DEBUG(0, "bulk out: wMaxPacketSize = %x\n", zd_le16_to_cpu(endpoint->wMaxPacketSize));
}
if ((endpoint->bEndpointAddress & 0x80) &&
((endpoint->bmAttributes & 3) == 0x03)) {
/* we found a interrupt in endpoint */
endpoint->bmAttributes &= ~3;
endpoint->bmAttributes |= 2;
interrupt_in_endpoint[num_interrupt_in] = endpoint;
++num_interrupt_in;
macp->in_interval = endpoint->bInterval;
ZD1211DEBUG(0, "interrupt in: wMaxPacketSize = %x\n", zd_le16_to_cpu(endpoint->wMaxPacketSize));
ZD1211DEBUG(0, "interrupt in: int_interval = %d\n", endpoint->bInterval);
}
if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
((endpoint->bmAttributes & 3) == 0x03)) {
/* we found a interrupt out endpoint */
endpoint->bmAttributes &= ~3;
endpoint->bmAttributes |= 2;
interrupt_out_endpoint[num_interrupt_out] = endpoint;
++num_interrupt_out;
macp->ep4isIntOut = 0;//1;
ZD1211DEBUG(0, "interrupt out: wMaxPacketSize = %x\n", zd_le16_to_cpu(endpoint->wMaxPacketSize));
macp->out_interval = endpoint->bInterval;
}
}
macp->num_bulk_in = num_bulk_in;
macp->num_bulk_out = num_bulk_out;
macp->num_interrupt_in = num_interrupt_in;
macp->num_interrupt_out = num_interrupt_out;
macp->rx_urb = USB_ALLOC_URB(0, GFP_KERNEL);
if (!macp->rx_urb)
return 0;
macp->tx_urb = USB_ALLOC_URB(0, GFP_KERNEL);
if (!macp->tx_urb) {
usb_free_urb(macp->rx_urb);
return 0;
}
macp->intr_urb = USB_ALLOC_URB(0, GFP_KERNEL);
if (!macp->intr_urb) {
usb_free_urb(macp->rx_urb);
usb_free_urb(macp->tx_urb);
return 0;
}
macp->ctrl_urb = USB_ALLOC_URB(0, GFP_KERNEL);
if (!macp->ctrl_urb) {
usb_free_urb(macp->rx_urb);
usb_free_urb(macp->tx_urb);
usb_free_urb(macp->intr_urb);
return 0;
}
macp->reg_urb = USB_ALLOC_URB(0, GFP_KERNEL);
if (!macp->reg_urb) {
usb_free_urb(macp->rx_urb);
usb_free_urb(macp->tx_urb);
usb_free_urb(macp->intr_urb);
usb_free_urb(macp->ctrl_urb);
return 0;
}
#if 0//(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
#if 1
macp->IntEPBuffer = kmalloc(MAX_EPINT_BUFFER, GFP_KERNEL);
#else //always failed? why???
macp->IntEPBuffer = usb_buffer_alloc(macp->device,
MAX_EPINT_BUFFER,
GFP_KERNEL,
&macp->IntBufferHandle);
#endif
if (!macp->IntEPBuffer){
FPRINT("usb_buffer_alloc failed");
usb_free_urb(macp->rx_urb);
usb_free_urb(macp->tx_urb);
usb_free_urb(macp->intr_urb);
usb_free_urb(macp->ctrl_urb);
usb_free_urb(macp->reg_urb);
return 0;
}
#endif
return 1;
}
void zd1211_free_all_urbs(struct zd1205_private *macp)
{
if (macp->rx_urb)
usb_free_urb(macp->rx_urb);
if (macp->tx_urb)
usb_free_urb(macp->tx_urb);
if (macp->intr_urb)
usb_free_urb(macp->intr_urb);
if (macp->ctrl_urb)
usb_free_urb(macp->ctrl_urb);
if (macp->reg_urb)
usb_free_urb(macp->reg_urb);
#if 0//(LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
if (macp->IntEPBuffer)
#if 1
kfree(macp->IntEPBuffer);
#else
usb_buffer_free(macp->device,
MAX_EPINT_BUFFER,
(void *)macp->IntEPBuffer,
macp->IntBufferHandle);
#endif
#endif
}
void zd1211_unlink_all_urbs(struct zd1205_private *macp)
{
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,8))
usb_kill_urb(macp->rx_urb);
usb_kill_urb(macp->tx_urb);
usb_kill_urb(macp->ctrl_urb);
usb_kill_urb(macp->reg_urb);
if (test_bit(ZD1211_UNPLUG, &macp->flags))
usb_kill_urb(macp->intr_urb);
#else
usb_unlink_urb(macp->rx_urb);
usb_unlink_urb(macp->tx_urb);
usb_unlink_urb(macp->ctrl_urb);
usb_unlink_urb(macp->reg_urb);
if (test_bit(ZD1211_UNPLUG, &macp->flags))
usb_unlink_urb(macp->intr_urb);
#endif
}
#define MAX_RX_MERGE_PACKET_NUM 3
void zd1211_rx_isr(unsigned long parm)
{
struct zd1205_private *macp = (struct zd1205_private *)parm;
struct urb *urb = macp->read_urb;
struct rx_list_elem *rx_struct;
#if fMERGE_RX_FRAME
struct rx_list_elem *rx_struct_array[MAX_RX_MERGE_PACKET_NUM];
int total_rx_struct = 1, rx_array_cnt = 0;
int i;
u32 tmpLen = 0;
u16 last_pkt_len;
#endif
u32 TotalLength = urb->actual_length;
u8 *pRxBuffer;
struct sk_buff *skb;
zd1205_RFD_t *rfd = NULL;
unsigned long flags;
spin_lock(&macp->intr_lock);
ZD1211DEBUG(4, "actual_length = %x\n", urb->actual_length);
rx_struct = list_entry(macp->active_rx_list.next,
struct rx_list_elem, list_elem);
skb = rx_struct->skb;
rfd = RFD_POINTER(skb, macp);
pRxBuffer = &rfd->RxBuffer[macp->rxOffset];
#if 0
//for debug only
zd1205_dump_data("pRxBuffer", (u8 *)pRxBuffer, TotalLength);
//zd1211_submit_rx_urb(macp);
//return;
#endif
#if fMERGE_RX_FRAME
if (rx_struct->UnFinishFrmLen){
TotalLength += rx_struct->UnFinishFrmLen;
rx_struct->UnFinishFrmLen = 0;
macp->CompLenInfoCnt++;
//ZD1211DEBUG(0, "Got Rx Frames Length Info!!\n");
}
last_pkt_len = TotalLength & (macp->wMaxPacketSize - 1);
if (last_pkt_len <= (macp->wMaxPacketSize - 4)){
if (zd_get_LE_U16(pRxBuffer + (TotalLength/sizeof(u16)-1)*2 ) == 0x697E) {
//if (((u16 *) pRxBuffer)[TotalLength / sizeof(u16) - 1] == 0x697E){
total_rx_struct = 3;
//ZD1211DEBUG(0, "Got merged Rx Frames!!\n");
//zd1205_dump_data("pRxBuffer", (u8 *)pRxBuffer, TotalLength);
macp->Continue2Rx++;
}
else
macp->NoMergedRxCnt++;
//ZD1211DEBUG(3, "last_pkt_len = %x\n", last_pkt_len);
//zd1205_dump_data("pRxBuffer", (u8 *)pRxBuffer, TotalLength);
for (i=0; i<total_rx_struct; i++){
int CurFrmLen;
if (total_rx_struct> 1){
CurFrmLen=zd_get_LE_U16(pRxBuffer+(TotalLength/sizeof(u16)+i-4)*2);
//ZD1211DEBUG(2, "CurFrmLen = %x\n", CurFrmLen);
}
else
CurFrmLen = TotalLength;
if (CurFrmLen == 0){
break;
}
flags = dot11Obj.EnterCS();
rx_struct_array[i] = list_entry(macp->active_rx_list.next,
struct rx_list_elem, list_elem);
list_del(&(rx_struct_array[i]->list_elem));
#if ZDCONF_DEFER_RX == 1
list_add_tail(&(rx_struct_array[i]->list_elem), &(macp->wait_rx_list));
#endif
dot11Obj.ExitCS(flags);
rx_array_cnt++;
ZD1211DEBUG(2, "CurFrmLen = %x\n", CurFrmLen);
skb = rx_struct_array[i]->skb;
rfd = RFD_POINTER(skb, macp);
rfd->CbStatus = RFD_STATUS_COMPLETE;
rfd->ActualCount = CurFrmLen;
if (i > 0){
memcpy(&rfd->RxBuffer[macp->rxOffset],
pRxBuffer + tmpLen,
rfd->ActualCount);
}
tmpLen += (rfd->ActualCount & ~0x03);
if (rfd->ActualCount & 0x03)
tmpLen += 4;
rfd->ActualCount += macp->rxOffset;
}
}
else {
// last_pkt_len = 509, 510, 511
// wait next Rx
//ZD1211DEBUG(0, "Wait Rx Frames Length Info!!\n");
//ZD1211DEBUG(2, "last_pkt_len = %x\n", last_pkt_len);
macp->WaitLenInfoCnt++;
rx_struct->UnFinishFrmLen = ((TotalLength / macp->wMaxPacketSize) + 1)
* (macp->wMaxPacketSize);
//zd1205_dump_data("pRxBuffer", (u8 *)pRxBuffer, TotalLength);
}
if(zd1211_submit_rx_urb(macp))
{
printk("No available buffer. Reallocate\n");
zd1211_alloc_rx((unsigned long)macp);
if(zd1211_submit_rx_urb(macp))
printk("zd1211_submit_rx_urb fail. Abort\n");
set_bit(0, &macp->rxurb_submit);
}
if (!rx_struct->UnFinishFrmLen){
#if ZDCONF_DEFER_RX == 1
defer_kevent(macp, KEVENT_DEFER_RX);
#else
macp->total_rx_cnt = rx_array_cnt;
macp->rx_struct_array = rx_struct_array;
zd1205_rx_isr(macp);
#endif
}
#else
rfd->CbStatus = RFD_STATUS_COMPLETE;
rfd->ActualCount = TotalLength + macp->rxOffset;
zd1205_rx_isr(macp);
#endif
if (dot11Obj.QueueFlag & MGT_QUEUE_SET)
defer_kevent(macp, KEVENT_PROCESS_SIGNAL);
spin_unlock(&macp->intr_lock);
}
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
void zd1211_rx_comp_cb(struct urb *urb)
#else
void zd1211_rx_comp_cb(struct urb *urb, struct pt_regs *regs)
#endif
{
struct zd1205_private *macp = urb->context;
static unsigned long lastErr = 0;
macp->lastRxComp = jiffies;
if ((!macp) || !test_bit(ZD1211_RUNNING, &macp->flags))
{
if(!macp)
printk("macp is NULL in %s\n", __FUNCTION__);
return;
}
if (!netif_device_present(macp->device))
{
printk("Error2 in %s\n", __FUNCTION__);
return;
}
if (urb->status != 0){
//Error occurs frequent when disconnect
if(jiffies-lastErr > HZ)
printk("Wrong @ %s, status=%d(%ld).", __FUNCTION__,urb->status,jiffies);
lastErr = jiffies;
if(urb->status == -EOVERFLOW)
{
printk("It's OK\n");
}
else
printk("\n");
zd1211_DumpErrorCode(macp, urb->status);
if ((urb->status != -ENOENT) &&
(macp->bUSBDeveiceAttached == 1) &&
(urb->status != -ECONNRESET) &&
(urb->status != -ESHUTDOWN)) {
//printk("nonzero read bulk status received: %d\n", urb->status);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
if (urb->status == USB_ST_INTERNALERROR)
{
printk("Error3 in %s\n", __FUNCTION__);
//return;
}
#else
if (urb->status == -EPIPE){
printk("nonzero read bulk status received: -EPIPE\n");
//return;
}
if (urb->status == -EPROTO){
printk("nonzero read bulk status received: -EPROTO\n");
//return;
}
#endif
if(zd1211_submit_rx_urb(macp))
{
printk("No available buffer. Reallocate\n");
zd1211_alloc_rx((unsigned long)macp);
if(zd1211_submit_rx_urb(macp))
printk("zd1211_submit_rx_urb fail. Abort\n");
set_bit(0, &macp->rxurb_submit);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -