Hi,
Finally I solved some problems running WiFi on DaVinci. Some tips
could help run other USB devices.
Tips:
1. Add delay 1 ms in probe function before FW loading.
2. Work on full usb speed, not high. You may use USB 1.1 hub or lower
MGC_M_POWER_HSENAB in MGC_O_HDRC_POWER.
3. Pay attention and fix bulk/interrupt URB types.
4. compile kernel with wireless support or configure driver with
configuration file (for example zd1211.conf, essid=....)
6. restart URB on timeout.
Please see attached patch for ZD1211LnxDrv_2_15_0_0 driver. The
patched driver works on FS, and have problems on HS.
--
Constantine Shulyupin
Embedded Linux Consultant
http://linuxdriver.co.il/
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/Makefile ZD1211LnxDrv_2_15_0_0.davinci/Makefile
*** ZD1211LnxDrv_2_15_0_0/Makefile 2006-07-07 10:42:52.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/Makefile 2007-02-07 13:28:15.000000000 +0200
***************
*** 4,17 ****
#
#
! CC=gcc
! CPP=g++
! LD=ld
rM=rm -f -r
# if the kernel is 2.6.x, trun on this
KERN_26=y
! KERNEL_SOURCE=/usr/src/linux-2.6.9
# if the kernel is 2.4.x, trun on this
#KERN_24=y
--- 4,17 ----
#
#
! #CC=gcc
! #CPP=g++
! #LD=ld
rM=rm -f -r
# if the kernel is 2.6.x, trun on this
KERN_26=y
! #KERNEL_SOURCE=/usr/src/linux-2.6.9
# if the kernel is 2.4.x, trun on this
#KERN_24=y
*************** DEFINES=-D__KERNEL__ -DMODULE=1
*** 24,30 ****
KERNRELEASE := $(shell uname -r;)
MODPATH := /lib/modules/$(KERNRELEASE)
!
ifeq ($(KERN_26), y)
--- 24,30 ----
KERNRELEASE := $(shell uname -r;)
MODPATH := /lib/modules/$(KERNRELEASE)
! ZD1211REV_B=1
ifeq ($(KERN_26), y)
*************** ifdef CONFIG_SMP
*** 47,53 ****
EXTRA_CFLAGS += -D__SMP__ -DSMP
endif
! KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
WLAN_SRC=$(PWD)
--- 47,54 ----
EXTRA_CFLAGS += -D__SMP__ -DSMP
endif
! #KDIR := /lib/modules/$(shell uname -r)/build
! KDIR=$(KERNEL_SOURCE)
PWD := $(shell pwd)
WLAN_SRC=$(PWD)
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zd1205.c ZD1211LnxDrv_2_15_0_0.davinci/src/zd1205.c
*** ZD1211LnxDrv_2_15_0_0/src/zd1205.c 2006-07-12 15:48:49.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zd1205.c 2007-02-05 15:16:59.000000000 +0200
*************** void zdcb_rx_ind(U8 *pData, U32 length,
*** 9726,9731 ****
--- 9726,9732 ----
case STA_ASSOCIATED:
case STA_REASSOCIATED:
+ printk("Associated\n");
macp->bAssoc = 1;
mTmRetryConnect=0;
iLED_ON(macp, macp->LinkLEDn);
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zd1211.c ZD1211LnxDrv_2_15_0_0.davinci/src/zd1211.c
*** ZD1211LnxDrv_2_15_0_0/src/zd1211.c 2006-07-11 11:43:55.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zd1211.c 2007-02-05 17:30:37.000000000 +0200
*************** out:
*** 457,462 ****
--- 457,477 ----
}
#endif
+ static void zd_fill_int_urb(struct zd1205_private *macp);
+ static void zd_fill_int_urb(struct zd1205_private *macp)
+ {
+ #if 1
+ usb_fill_int_urb(macp->intr_urb, macp->usb,
+ usb_rcvintpipe(macp->usb, EP_INT_IN),
+ macp->IntEPBuffer, MAX_EPINT_BUFFER,
+ zd1211_intr_cb, macp, macp->in_interval);
+ #else //fake it
+ usb_fill_bulk_urb(macp->intr_urb, macp->usb,
+ usb_rcvbulkpipe(macp->usb, EP_INT_IN),
+ macp->IntEPBuffer, MAX_EPINT_BUFFER,
+ zd1211_intr_cb, macp);
+ #endif
+ }
// return 0: success
int zd1211_USB_PACKAGE_READ_REGISTER(u16 *Address, u16 *pValue, u16 RegCount, u8 bAddUSBCSRAddress)
*************** int zd1211_USB_PACKAGE_READ_REGISTER(u16
*** 468,474 ****
u16 bufSize;
int ii;
//int memflags = GFP_KERNEL;
!
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
if (in_interrupt()){
#else
--- 483,489 ----
u16 bufSize;
int ii;
//int memflags = GFP_KERNEL;
! //mdelay(100);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
if (in_interrupt()){
#else
*************** int zd1211_USB_PACKAGE_READ_REGISTER(u16
*** 476,488 ****
if (in_atomic()){
#endif
printk(KERN_ERR "********zd1211_USB_PACKAGE_READ_REGISTER in_interrupt*********\n");
! return 0;
}
down(&macp->reg_sem);
if ((RegCount == 0) || (!macp->bUSBDeveiceAttached) || (!test_bit(ZD1211_RUNNING, &macp->flags))){
up(&macp->reg_sem);
! return 0;
}
pRegBuffer = kmalloc(size, GFP_KERNEL);
--- 491,503 ----
if (in_atomic()){
#endif
printk(KERN_ERR "********zd1211_USB_PACKAGE_READ_REGISTER in_interrupt*********\n");
! return -1;
}
down(&macp->reg_sem);
if ((RegCount == 0) || (!macp->bUSBDeveiceAttached) || (!test_bit(ZD1211_RUNNING, &macp->flags))){
up(&macp->reg_sem);
! return -1;
}
pRegBuffer = kmalloc(size, GFP_KERNEL);
*************** int zd1211_USB_PACKAGE_READ_REGISTER(u16
*** 575,580 ****
--- 590,610 ----
if (test_bit(ZD1211_REQ_COMP, &macp->flags))
macp->regRspCompCnt++;
else{
+ {
+ int res;
+ printk("%s: warning, restarting INT EP\n",__FUNCTION__);
+ //dump_urb(macp->intr_urb);
+ //usb_kill_urb(macp->intr_urb);
+ usb_free_urb(macp->intr_urb);
+ macp->intr_urb = USB_ALLOC_URB(0, GFP_KERNEL);
+ zd_fill_int_urb(macp);
+ if ((res = SUBMIT_URB(macp->intr_urb, GFP_KERNEL))){
+ printk(KERN_ERR "zd1211: failed intr_urb\n");
+ zd1211_DumpErrorCode(macp, res);
+ return -1;
+ }
+ macp->bUSBDeveiceAttached=1;
+ }
memset(macp->IntEPBuffer, 0x0, MAX_EPINT_BUFFER);
macp->regUnCompCnt++;
ret = -1;
*************** u32 zd1211_readl(u32 Address, u8 bAddUSB
*** 624,637 ****
while (bRet != 0){
bRet = zd1211_USB_PACKAGE_READ_REGISTER(ReadAddr, ReadData, 2, false);
count++;
if (count > 5){
printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious");
! break;
}
}
!
value = (((u32) ReadData[1]) << 16) + ReadData[0];
return value;
}
--- 654,668 ----
while (bRet != 0){
bRet = zd1211_USB_PACKAGE_READ_REGISTER(ReadAddr, ReadData, 2, false);
+ if (!bRet) break; // OK
count++;
if (count > 5){
printk(KERN_ERR "1211_readl failed for 5 attempts...Very Serious");
! return 0;
}
}
! if (count) printk("%s retry OK\n",__FUNCTION__);
value = (((u32) ReadData[1]) << 16) + ReadData[0];
return value;
}
*************** int zd1211_USB_PACKAGE_WRITE_REGISTER(u1
*** 645,650 ****
--- 676,682 ----
u16 size = sizeof(USB_WRITE_REG);
u16 bufSize;
int i;
+ //mdelay(100);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
if (in_interrupt()){
*************** u8 zd1211_InitSetup(struct net_device *d
*** 1827,1833 ****
macp->in_interval = 10;
#endif
! #if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
usb_fill_int_urb(macp->intr_urb, macp->usb,
usb_rcvintpipe(macp->usb, EP_INT_IN),
macp->IntEPBuffer, MAX_EPINT_BUFFER,
--- 1859,1865 ----
macp->in_interval = 10;
#endif
! /*#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0))
usb_fill_int_urb(macp->intr_urb, macp->usb,
usb_rcvintpipe(macp->usb, EP_INT_IN),
macp->IntEPBuffer, MAX_EPINT_BUFFER,
*************** u8 zd1211_InitSetup(struct net_device *d
*** 1837,1843 ****
usb_rcvbulkpipe(macp->usb, EP_INT_IN),
macp->IntEPBuffer, MAX_EPINT_BUFFER,
zd1211_intr_cb, macp);
! #endif
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))
macp->intr_urb->transfer_flags |= URB_ASYNC_UNLINK;
--- 1869,1876 ----
usb_rcvbulkpipe(macp->usb, EP_INT_IN),
macp->IntEPBuffer, MAX_EPINT_BUFFER,
zd1211_intr_cb, macp);
! #endif*/
! zd_fill_int_urb(macp);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))
macp->intr_urb->transfer_flags |= URB_ASYNC_UNLINK;
*************** void zd1211_intr_cb(struct urb *urb, str
*** 2357,2363 ****
zd1211_DumpErrorCode(macp, urb->status);
if (urb->status == -ENODEV){ //device was removed
! FPRINT("Device was removed!!!");
macp->bUSBDeveiceAttached = 0;
wake_up(&macp->regSet_wait);
--- 2390,2396 ----
zd1211_DumpErrorCode(macp, urb->status);
if (urb->status == -ENODEV){ //device was removed
! printk("Device was removed!!!\n");
macp->bUSBDeveiceAttached = 0;
wake_up(&macp->regSet_wait);
*************** void zd1211_intr_cb(struct urb *urb, str
*** 2375,2381 ****
case -EPROTO:
#endif
macp->bUSBDeveiceAttached = 0;
! FPRINT("Device was down!!!");
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
spin_unlock(&macp->intr_lock);
return;
--- 2408,2414 ----
case -EPROTO:
#endif
macp->bUSBDeveiceAttached = 0;
! printk("Device was down!!!");
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
spin_unlock(&macp->intr_lock);
return;
*************** void zd1211_intr_cb(struct urb *urb, str
*** 2464,2473 ****
//memset(macp->IntEPBuffer, 0x0, MAX_EPINT_BUFFER);
//use bulk instead of interrupt in
! usb_fill_bulk_urb(macp->intr_urb, macp->usb,
usb_rcvbulkpipe(macp->usb, EP_INT_IN),
macp->IntEPBuffer, MAX_EPINT_BUFFER,
! zd1211_intr_cb, macp);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))
macp->intr_urb->transfer_flags |= URB_ASYNC_UNLINK;
#endif
--- 2497,2507 ----
//memset(macp->IntEPBuffer, 0x0, MAX_EPINT_BUFFER);
//use bulk instead of interrupt in
! /*usb_fill_bulk_urb(macp->intr_urb, macp->usb,
usb_rcvbulkpipe(macp->usb, EP_INT_IN),
macp->IntEPBuffer, MAX_EPINT_BUFFER,
! zd1211_intr_cb, macp); */
! zd_fill_int_urb(macp);
#if (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,14))
macp->intr_urb->transfer_flags |= URB_ASYNC_UNLINK;
#endif
*************** int zd1211_LoadUSBSpecCode(struct zd1205
*** 3106,3113 ****
while (uImgLength > 0) {
int translen = (uImgLength > 4096) ? 4096 : uImgLength;
! ZD1211DEBUG(0, "translen = %x\n", translen);
! ZD1211DEBUG(0, "uCodeOfst = %x\n", uCodeOfst);
result = usb_control_msg(macp->usb, usb_sndctrlpipe(macp->usb, 0),
--- 3140,3147 ----
while (uImgLength > 0) {
int translen = (uImgLength > 4096) ? 4096 : uImgLength;
! ZD1211DEBUG(1, "translen = %x\n", translen);
! ZD1211DEBUG(1, "uCodeOfst = %x\n", uCodeOfst);
result = usb_control_msg(macp->usb, usb_sndctrlpipe(macp->usb, 0),
*************** int zd1211_LoadUSBSpecCode(struct zd1205
*** 3116,3127 ****
image, translen, HZ);
ZD1211DEBUG(0, "result = %x\n", result);
! if(result != translen)
{
printk("##### Warning! ####\n");
printk("usb_control_msg doesn't send all data out\n");
printk("You need to decrease the message amount in each send\n");
! }
if (result < 0) {
--- 3150,3161 ----
image, translen, HZ);
ZD1211DEBUG(0, "result = %x\n", result);
! /*if(result != translen)
{
printk("##### Warning! ####\n");
printk("usb_control_msg doesn't send all data out\n");
printk("You need to decrease the message amount in each send\n");
! }*/
if (result < 0) {
*************** int zd1211_LoadUSBSpecCode(struct zd1205
*** 3130,3135 ****
--- 3164,3170 ----
}
+ translen = result & ~1;
uImgLength -= translen;
image += translen;
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zdhw.c ZD1211LnxDrv_2_15_0_0.davinci/src/zdhw.c
*** ZD1211LnxDrv_2_15_0_0/src/zdhw.c 2006-07-07 10:42:52.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zdhw.c 2007-02-05 15:58:35.000000000 +0200
*************** void HW_SwitchChannel(zd_80211Obj_t *pOb
*** 3243,3249 ****
switch(pObj->rfMode)
{
default:
! printk("Invalid RF module parameter:%lu", pObj->rfMode);
break;
/*
--- 3243,3249 ----
switch(pObj->rfMode)
{
default:
! printk("Invalid RF module parameter:%lu\n", pObj->rfMode);
break;
/*
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zdsynch.c ZD1211LnxDrv_2_15_0_0.davinci/src/zdsynch.c
*** ZD1211LnxDrv_2_15_0_0/src/zdsynch.c 2006-07-07 10:42:52.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zdsynch.c 2007-02-05 15:18:19.000000000 +0200
*************** BOOLEAN ProbeRsp_Beacon(Signal_t *signal
*** 294,299 ****
--- 294,300 ----
if (!getElem(rdu, EID_SSID, &pCurrBssInfo->ssid,1)){
goto release;
}
+ printk("%s: ssid=%s\n",__FUNCTION__,&(pCurrBssInfo->ssid.buf[2]));
if (!getElem(rdu, EID_SUPRATES, &pCurrBssInfo->supRates,1)){
goto release;
diff -p -B -w -b -r -X /home/conan/cmnd/d.x ZD1211LnxDrv_2_15_0_0/src/zdusb.c ZD1211LnxDrv_2_15_0_0.davinci/src/zdusb.c
*** ZD1211LnxDrv_2_15_0_0/src/zdusb.c 2006-07-07 10:42:52.000000000 +0300
--- ZD1211LnxDrv_2_15_0_0.davinci/src/zdusb.c 2007-02-07 13:27:34.000000000 +0200
*************** static int zd1211_probe(struct usb_inter
*** 132,138 ****
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
usb_get_dev(dev);
#endif
!
vendor_id = zd_le16_to_cpu(dev->descriptor.idVendor);
product_id = zd_le16_to_cpu(dev->descriptor.idProduct);
--- 132,138 ----
#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0))
usb_get_dev(dev);
#endif
! mdelay(1); // workaround loading FW bug
vendor_id = zd_le16_to_cpu(dev->descriptor.idVendor);
product_id = zd_le16_to_cpu(dev->descriptor.idProduct);
_______________________________________________
Davinci-linux-open-source mailing list
[email protected]
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source