blob: 6215e3ca418aa00c4bf031677675c7f0c32d468a [file] [log] [blame]
Pavel Machek66101de2008-10-01 14:36:56 +02001#include "sysdef.h"
2
3extern void phy_calibration_winbond(hw_data_t *phw_data, u32 frequency);
4
Pekka Enberg279b6cc2008-10-27 22:46:39 +02005// true : read command process successfully
6// false : register not support
Pavel Machek66101de2008-10-01 14:36:56 +02007// RegisterNo : start base
8// pRegisterData : data point
9// NumberOfData : number of register data
10// Flag : AUTO_INCREMENT - RegisterNo will auto increment 4
11// NO_INCREMENT - Function will write data into the same register
12unsigned char
Pekka Enberg8b384e02008-10-21 00:03:41 +030013Wb35Reg_BurstWrite(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterData, u8 NumberOfData, u8 Flag)
Pavel Machek66101de2008-10-01 14:36:56 +020014{
Pekka Enberg65144de2008-10-22 11:02:37 +030015 struct wb35_reg *reg = &pHwData->reg;
Pekka Enberga55a89b2008-10-22 11:01:16 +030016 struct urb *urb = NULL;
Pekka Enbergf37435c2008-10-22 11:01:47 +030017 struct wb35_reg_queue *reg_queue = NULL;
Pavel Machek66101de2008-10-01 14:36:56 +020018 u16 UrbSize;
19 struct usb_ctrlrequest *dr;
20 u16 i, DataSize = NumberOfData*4;
21
22 // Module shutdown
23 if (pHwData->SurpriseRemove)
Pekka Enberg279b6cc2008-10-27 22:46:39 +020024 return false;
Pavel Machek66101de2008-10-01 14:36:56 +020025
26 // Trying to use burst write function if use new hardware
Pekka Enbergf37435c2008-10-22 11:01:47 +030027 UrbSize = sizeof(struct wb35_reg_queue) + DataSize + sizeof(struct usb_ctrlrequest);
Pekka Enbergc8b2b702008-10-27 22:47:12 +020028 reg_queue = kzalloc(UrbSize, GFP_ATOMIC);
Greg Kroah-Hartmanf3d20182008-10-27 14:21:24 -070029 urb = usb_alloc_urb(0, GFP_ATOMIC);
Pekka Enbergf37435c2008-10-22 11:01:47 +030030 if( urb && reg_queue ) {
31 reg_queue->DIRECT = 2;// burst write register
32 reg_queue->INDEX = RegisterNo;
33 reg_queue->pBuffer = (u32 *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue));
34 memcpy( reg_queue->pBuffer, pRegisterData, DataSize );
Pavel Machek66101de2008-10-01 14:36:56 +020035 //the function for reversing register data from little endian to big endian
36 for( i=0; i<NumberOfData ; i++ )
Pekka Enbergf37435c2008-10-22 11:01:47 +030037 reg_queue->pBuffer[i] = cpu_to_le32( reg_queue->pBuffer[i] );
Pavel Machek66101de2008-10-01 14:36:56 +020038
Pekka Enbergf37435c2008-10-22 11:01:47 +030039 dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue) + DataSize);
Pavel Machek66101de2008-10-01 14:36:56 +020040 dr->bRequestType = USB_TYPE_VENDOR | USB_DIR_OUT | USB_RECIP_DEVICE;
41 dr->bRequest = 0x04; // USB or vendor-defined request code, burst mode
42 dr->wValue = cpu_to_le16( Flag ); // 0: Register number auto-increment, 1: No auto increment
43 dr->wIndex = cpu_to_le16( RegisterNo );
44 dr->wLength = cpu_to_le16( DataSize );
Pekka Enbergf37435c2008-10-22 11:01:47 +030045 reg_queue->Next = NULL;
46 reg_queue->pUsbReq = dr;
47 reg_queue->urb = urb;
Pavel Machek66101de2008-10-01 14:36:56 +020048
Pekka Enberg65144de2008-10-22 11:02:37 +030049 spin_lock_irq( &reg->EP0VM_spin_lock );
50 if (reg->reg_first == NULL)
51 reg->reg_first = reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +020052 else
Pekka Enberg65144de2008-10-22 11:02:37 +030053 reg->reg_last->Next = reg_queue;
54 reg->reg_last = reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +020055
Pekka Enberg65144de2008-10-22 11:02:37 +030056 spin_unlock_irq( &reg->EP0VM_spin_lock );
Pavel Machek66101de2008-10-01 14:36:56 +020057
58 // Start EP0VM
59 Wb35Reg_EP0VM_start(pHwData);
60
Pekka Enberg279b6cc2008-10-27 22:46:39 +020061 return true;
Pavel Machek66101de2008-10-01 14:36:56 +020062 } else {
Pekka Enberga55a89b2008-10-22 11:01:16 +030063 if (urb)
64 usb_free_urb(urb);
Pekka Enbergf37435c2008-10-22 11:01:47 +030065 if (reg_queue)
66 kfree(reg_queue);
Pekka Enberg279b6cc2008-10-27 22:46:39 +020067 return false;
Pavel Machek66101de2008-10-01 14:36:56 +020068 }
Pekka Enberg279b6cc2008-10-27 22:46:39 +020069 return false;
Pavel Machek66101de2008-10-01 14:36:56 +020070}
71
72void
73Wb35Reg_Update(phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue)
74{
Pekka Enberg65144de2008-10-22 11:02:37 +030075 struct wb35_reg *reg = &pHwData->reg;
Pavel Machek66101de2008-10-01 14:36:56 +020076 switch (RegisterNo) {
Pekka Enberg65144de2008-10-22 11:02:37 +030077 case 0x3b0: reg->U1B0 = RegisterValue; break;
78 case 0x3bc: reg->U1BC_LEDConfigure = RegisterValue; break;
79 case 0x400: reg->D00_DmaControl = RegisterValue; break;
80 case 0x800: reg->M00_MacControl = RegisterValue; break;
81 case 0x804: reg->M04_MulticastAddress1 = RegisterValue; break;
82 case 0x808: reg->M08_MulticastAddress2 = RegisterValue; break;
83 case 0x824: reg->M24_MacControl = RegisterValue; break;
84 case 0x828: reg->M28_MacControl = RegisterValue; break;
85 case 0x82c: reg->M2C_MacControl = RegisterValue; break;
86 case 0x838: reg->M38_MacControl = RegisterValue; break;
87 case 0x840: reg->M40_MacControl = RegisterValue; break;
88 case 0x844: reg->M44_MacControl = RegisterValue; break;
89 case 0x848: reg->M48_MacControl = RegisterValue; break;
90 case 0x84c: reg->M4C_MacStatus = RegisterValue; break;
91 case 0x860: reg->M60_MacControl = RegisterValue; break;
92 case 0x868: reg->M68_MacControl = RegisterValue; break;
93 case 0x870: reg->M70_MacControl = RegisterValue; break;
94 case 0x874: reg->M74_MacControl = RegisterValue; break;
95 case 0x878: reg->M78_ERPInformation = RegisterValue; break;
96 case 0x87C: reg->M7C_MacControl = RegisterValue; break;
97 case 0x880: reg->M80_MacControl = RegisterValue; break;
98 case 0x884: reg->M84_MacControl = RegisterValue; break;
99 case 0x888: reg->M88_MacControl = RegisterValue; break;
100 case 0x898: reg->M98_MacControl = RegisterValue; break;
101 case 0x100c: reg->BB0C = RegisterValue; break;
102 case 0x102c: reg->BB2C = RegisterValue; break;
103 case 0x1030: reg->BB30 = RegisterValue; break;
104 case 0x103c: reg->BB3C = RegisterValue; break;
105 case 0x1048: reg->BB48 = RegisterValue; break;
106 case 0x104c: reg->BB4C = RegisterValue; break;
107 case 0x1050: reg->BB50 = RegisterValue; break;
108 case 0x1054: reg->BB54 = RegisterValue; break;
109 case 0x1058: reg->BB58 = RegisterValue; break;
110 case 0x105c: reg->BB5C = RegisterValue; break;
111 case 0x1060: reg->BB60 = RegisterValue; break;
Pavel Machek66101de2008-10-01 14:36:56 +0200112 }
113}
114
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200115// true : read command process successfully
116// false : register not support
Pavel Machek66101de2008-10-01 14:36:56 +0200117unsigned char
118Wb35Reg_WriteSync( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
119{
Pekka Enberg65144de2008-10-22 11:02:37 +0300120 struct wb35_reg *reg = &pHwData->reg;
Pavel Machek66101de2008-10-01 14:36:56 +0200121 int ret = -1;
122
123 // Module shutdown
124 if (pHwData->SurpriseRemove)
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200125 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200126
127 RegisterValue = cpu_to_le32(RegisterValue);
128
129 // update the register by send usb message------------------------------------
Pekka Enberg65144de2008-10-22 11:02:37 +0300130 reg->SyncIoPause = 1;
Pavel Machek66101de2008-10-01 14:36:56 +0200131
132 // 20060717.5 Wait until EP0VM stop
Pekka Enberg65144de2008-10-22 11:02:37 +0300133 while (reg->EP0vm_state != VM_STOP)
Pekka Enberg34222e02008-10-22 19:07:03 +0300134 msleep(10);
Pavel Machek66101de2008-10-01 14:36:56 +0200135
136 // Sync IoCallDriver
Pekka Enberg65144de2008-10-22 11:02:37 +0300137 reg->EP0vm_state = VM_RUNNING;
Pavel Machek66101de2008-10-01 14:36:56 +0200138 ret = usb_control_msg( pHwData->WbUsb.udev,
139 usb_sndctrlpipe( pHwData->WbUsb.udev, 0 ),
140 0x03, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_DIR_OUT,
141 0x0,RegisterNo, &RegisterValue, 4, HZ*100 );
Pekka Enberg65144de2008-10-22 11:02:37 +0300142 reg->EP0vm_state = VM_STOP;
143 reg->SyncIoPause = 0;
Pavel Machek66101de2008-10-01 14:36:56 +0200144
145 Wb35Reg_EP0VM_start(pHwData);
146
147 if (ret < 0) {
148 #ifdef _PE_REG_DUMP_
149 WBDEBUG(("EP0 Write register usb message sending error\n"));
150 #endif
151
152 pHwData->SurpriseRemove = 1; // 20060704.2
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200153 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200154 }
155
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200156 return true;
Pavel Machek66101de2008-10-01 14:36:56 +0200157}
158
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200159// true : read command process successfully
160// false : register not support
Pavel Machek66101de2008-10-01 14:36:56 +0200161unsigned char
162Wb35Reg_Write( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue )
163{
Pekka Enberg65144de2008-10-22 11:02:37 +0300164 struct wb35_reg *reg = &pHwData->reg;
Pavel Machek66101de2008-10-01 14:36:56 +0200165 struct usb_ctrlrequest *dr;
Pekka Enberga55a89b2008-10-22 11:01:16 +0300166 struct urb *urb = NULL;
Pekka Enbergf37435c2008-10-22 11:01:47 +0300167 struct wb35_reg_queue *reg_queue = NULL;
Pavel Machek66101de2008-10-01 14:36:56 +0200168 u16 UrbSize;
169
170
171 // Module shutdown
172 if (pHwData->SurpriseRemove)
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200173 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200174
175 // update the register by send urb request------------------------------------
Pekka Enbergf37435c2008-10-22 11:01:47 +0300176 UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest);
Pekka Enbergc8b2b702008-10-27 22:47:12 +0200177 reg_queue = kzalloc(UrbSize, GFP_ATOMIC);
Greg Kroah-Hartmanf3d20182008-10-27 14:21:24 -0700178 urb = usb_alloc_urb(0, GFP_ATOMIC);
Pekka Enbergf37435c2008-10-22 11:01:47 +0300179 if (urb && reg_queue) {
180 reg_queue->DIRECT = 1;// burst write register
181 reg_queue->INDEX = RegisterNo;
182 reg_queue->VALUE = cpu_to_le32(RegisterValue);
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200183 reg_queue->RESERVED_VALID = false;
Pekka Enbergf37435c2008-10-22 11:01:47 +0300184 dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue));
Pavel Machek66101de2008-10-01 14:36:56 +0200185 dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE;
186 dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode
187 dr->wValue = cpu_to_le16(0x0);
188 dr->wIndex = cpu_to_le16(RegisterNo);
189 dr->wLength = cpu_to_le16(4);
190
191 // Enter the sending queue
Pekka Enbergf37435c2008-10-22 11:01:47 +0300192 reg_queue->Next = NULL;
193 reg_queue->pUsbReq = dr;
194 reg_queue->urb = urb;
Pavel Machek66101de2008-10-01 14:36:56 +0200195
Pekka Enberg65144de2008-10-22 11:02:37 +0300196 spin_lock_irq(&reg->EP0VM_spin_lock );
197 if (reg->reg_first == NULL)
198 reg->reg_first = reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200199 else
Pekka Enberg65144de2008-10-22 11:02:37 +0300200 reg->reg_last->Next = reg_queue;
201 reg->reg_last = reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200202
Pekka Enberg65144de2008-10-22 11:02:37 +0300203 spin_unlock_irq( &reg->EP0VM_spin_lock );
Pavel Machek66101de2008-10-01 14:36:56 +0200204
205 // Start EP0VM
206 Wb35Reg_EP0VM_start(pHwData);
207
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200208 return true;
Pavel Machek66101de2008-10-01 14:36:56 +0200209 } else {
Pekka Enberga55a89b2008-10-22 11:01:16 +0300210 if (urb)
211 usb_free_urb(urb);
Pekka Enbergf37435c2008-10-22 11:01:47 +0300212 kfree(reg_queue);
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200213 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200214 }
215}
216
217//This command will be executed with a user defined value. When it completes,
218//this value is useful. For example, hal_set_current_channel will use it.
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200219// true : read command process successfully
220// false : register not support
Pavel Machek66101de2008-10-01 14:36:56 +0200221unsigned char
222Wb35Reg_WriteWithCallbackValue( phw_data_t pHwData, u16 RegisterNo, u32 RegisterValue,
Pekka Enberg8b384e02008-10-21 00:03:41 +0300223 s8 *pValue, s8 Len)
Pavel Machek66101de2008-10-01 14:36:56 +0200224{
Pekka Enberg65144de2008-10-22 11:02:37 +0300225 struct wb35_reg *reg = &pHwData->reg;
Pavel Machek66101de2008-10-01 14:36:56 +0200226 struct usb_ctrlrequest *dr;
Pekka Enberga55a89b2008-10-22 11:01:16 +0300227 struct urb *urb = NULL;
Pekka Enbergf37435c2008-10-22 11:01:47 +0300228 struct wb35_reg_queue *reg_queue = NULL;
Pavel Machek66101de2008-10-01 14:36:56 +0200229 u16 UrbSize;
230
231 // Module shutdown
232 if (pHwData->SurpriseRemove)
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200233 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200234
235 // update the register by send urb request------------------------------------
Pekka Enbergf37435c2008-10-22 11:01:47 +0300236 UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest);
Pekka Enbergc8b2b702008-10-27 22:47:12 +0200237 reg_queue = kzalloc(UrbSize, GFP_ATOMIC);
Greg Kroah-Hartmanf3d20182008-10-27 14:21:24 -0700238 urb = usb_alloc_urb(0, GFP_ATOMIC);
Pekka Enbergf37435c2008-10-22 11:01:47 +0300239 if (urb && reg_queue) {
240 reg_queue->DIRECT = 1;// burst write register
241 reg_queue->INDEX = RegisterNo;
242 reg_queue->VALUE = cpu_to_le32(RegisterValue);
Pavel Machek66101de2008-10-01 14:36:56 +0200243 //NOTE : Users must guarantee the size of value will not exceed the buffer size.
Pekka Enbergf37435c2008-10-22 11:01:47 +0300244 memcpy(reg_queue->RESERVED, pValue, Len);
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200245 reg_queue->RESERVED_VALID = true;
Pekka Enbergf37435c2008-10-22 11:01:47 +0300246 dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue));
Pavel Machek66101de2008-10-01 14:36:56 +0200247 dr->bRequestType = USB_TYPE_VENDOR|USB_DIR_OUT |USB_RECIP_DEVICE;
248 dr->bRequest = 0x03; // USB or vendor-defined request code, burst mode
249 dr->wValue = cpu_to_le16(0x0);
250 dr->wIndex = cpu_to_le16(RegisterNo);
251 dr->wLength = cpu_to_le16(4);
252
253 // Enter the sending queue
Pekka Enbergf37435c2008-10-22 11:01:47 +0300254 reg_queue->Next = NULL;
255 reg_queue->pUsbReq = dr;
256 reg_queue->urb = urb;
Pekka Enberg65144de2008-10-22 11:02:37 +0300257 spin_lock_irq (&reg->EP0VM_spin_lock );
258 if( reg->reg_first == NULL )
259 reg->reg_first = reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200260 else
Pekka Enberg65144de2008-10-22 11:02:37 +0300261 reg->reg_last->Next = reg_queue;
262 reg->reg_last = reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200263
Pekka Enberg65144de2008-10-22 11:02:37 +0300264 spin_unlock_irq ( &reg->EP0VM_spin_lock );
Pavel Machek66101de2008-10-01 14:36:56 +0200265
266 // Start EP0VM
267 Wb35Reg_EP0VM_start(pHwData);
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200268 return true;
Pavel Machek66101de2008-10-01 14:36:56 +0200269 } else {
Pekka Enberga55a89b2008-10-22 11:01:16 +0300270 if (urb)
271 usb_free_urb(urb);
Pekka Enbergf37435c2008-10-22 11:01:47 +0300272 kfree(reg_queue);
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200273 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200274 }
275}
276
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200277// true : read command process successfully
278// false : register not support
Pavel Machek66101de2008-10-01 14:36:56 +0200279// pRegisterValue : It must be a resident buffer due to asynchronous read register.
280unsigned char
Pekka Enberg8b384e02008-10-21 00:03:41 +0300281Wb35Reg_ReadSync( phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
Pavel Machek66101de2008-10-01 14:36:56 +0200282{
Pekka Enberg65144de2008-10-22 11:02:37 +0300283 struct wb35_reg *reg = &pHwData->reg;
Pekka Enberg8b384e02008-10-21 00:03:41 +0300284 u32 * pltmp = pRegisterValue;
Pavel Machek66101de2008-10-01 14:36:56 +0200285 int ret = -1;
286
287 // Module shutdown
288 if (pHwData->SurpriseRemove)
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200289 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200290
291 // Read the register by send usb message------------------------------------
292
Pekka Enberg65144de2008-10-22 11:02:37 +0300293 reg->SyncIoPause = 1;
Pavel Machek66101de2008-10-01 14:36:56 +0200294
295 // 20060717.5 Wait until EP0VM stop
Pekka Enberg65144de2008-10-22 11:02:37 +0300296 while (reg->EP0vm_state != VM_STOP)
Pekka Enberg34222e02008-10-22 19:07:03 +0300297 msleep(10);
Pavel Machek66101de2008-10-01 14:36:56 +0200298
Pekka Enberg65144de2008-10-22 11:02:37 +0300299 reg->EP0vm_state = VM_RUNNING;
Pavel Machek66101de2008-10-01 14:36:56 +0200300 ret = usb_control_msg( pHwData->WbUsb.udev,
301 usb_rcvctrlpipe(pHwData->WbUsb.udev, 0),
302 0x01, USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN,
303 0x0, RegisterNo, pltmp, 4, HZ*100 );
304
305 *pRegisterValue = cpu_to_le32(*pltmp);
306
Pekka Enberg65144de2008-10-22 11:02:37 +0300307 reg->EP0vm_state = VM_STOP;
Pavel Machek66101de2008-10-01 14:36:56 +0200308
309 Wb35Reg_Update( pHwData, RegisterNo, *pRegisterValue );
Pekka Enberg65144de2008-10-22 11:02:37 +0300310 reg->SyncIoPause = 0;
Pavel Machek66101de2008-10-01 14:36:56 +0200311
312 Wb35Reg_EP0VM_start( pHwData );
313
314 if (ret < 0) {
315 #ifdef _PE_REG_DUMP_
316 WBDEBUG(("EP0 Read register usb message sending error\n"));
317 #endif
318
319 pHwData->SurpriseRemove = 1; // 20060704.2
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200320 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200321 }
322
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200323 return true;
Pavel Machek66101de2008-10-01 14:36:56 +0200324}
325
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200326// true : read command process successfully
327// false : register not support
Pavel Machek66101de2008-10-01 14:36:56 +0200328// pRegisterValue : It must be a resident buffer due to asynchronous read register.
329unsigned char
Pekka Enberg8b384e02008-10-21 00:03:41 +0300330Wb35Reg_Read(phw_data_t pHwData, u16 RegisterNo, u32 * pRegisterValue )
Pavel Machek66101de2008-10-01 14:36:56 +0200331{
Pekka Enberg65144de2008-10-22 11:02:37 +0300332 struct wb35_reg *reg = &pHwData->reg;
Pavel Machek66101de2008-10-01 14:36:56 +0200333 struct usb_ctrlrequest * dr;
Pekka Enberga55a89b2008-10-22 11:01:16 +0300334 struct urb *urb;
Pekka Enbergf37435c2008-10-22 11:01:47 +0300335 struct wb35_reg_queue *reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200336 u16 UrbSize;
337
338 // Module shutdown
339 if (pHwData->SurpriseRemove)
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200340 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200341
342 // update the variable by send Urb to read register ------------------------------------
Pekka Enbergf37435c2008-10-22 11:01:47 +0300343 UrbSize = sizeof(struct wb35_reg_queue) + sizeof(struct usb_ctrlrequest);
Pekka Enbergc8b2b702008-10-27 22:47:12 +0200344 reg_queue = kzalloc(UrbSize, GFP_ATOMIC);
Greg Kroah-Hartmanf3d20182008-10-27 14:21:24 -0700345 urb = usb_alloc_urb(0, GFP_ATOMIC);
Pekka Enbergf37435c2008-10-22 11:01:47 +0300346 if( urb && reg_queue )
Pavel Machek66101de2008-10-01 14:36:56 +0200347 {
Pekka Enbergf37435c2008-10-22 11:01:47 +0300348 reg_queue->DIRECT = 0;// read register
349 reg_queue->INDEX = RegisterNo;
350 reg_queue->pBuffer = pRegisterValue;
351 dr = (struct usb_ctrlrequest *)((u8 *)reg_queue + sizeof(struct wb35_reg_queue));
Pavel Machek66101de2008-10-01 14:36:56 +0200352 dr->bRequestType = USB_TYPE_VENDOR|USB_RECIP_DEVICE|USB_DIR_IN;
353 dr->bRequest = 0x01; // USB or vendor-defined request code, burst mode
354 dr->wValue = cpu_to_le16(0x0);
355 dr->wIndex = cpu_to_le16 (RegisterNo);
356 dr->wLength = cpu_to_le16 (4);
357
358 // Enter the sending queue
Pekka Enbergf37435c2008-10-22 11:01:47 +0300359 reg_queue->Next = NULL;
360 reg_queue->pUsbReq = dr;
361 reg_queue->urb = urb;
Pekka Enberg65144de2008-10-22 11:02:37 +0300362 spin_lock_irq ( &reg->EP0VM_spin_lock );
363 if( reg->reg_first == NULL )
364 reg->reg_first = reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200365 else
Pekka Enberg65144de2008-10-22 11:02:37 +0300366 reg->reg_last->Next = reg_queue;
367 reg->reg_last = reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200368
Pekka Enberg65144de2008-10-22 11:02:37 +0300369 spin_unlock_irq( &reg->EP0VM_spin_lock );
Pavel Machek66101de2008-10-01 14:36:56 +0200370
371 // Start EP0VM
372 Wb35Reg_EP0VM_start( pHwData );
373
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200374 return true;
Pavel Machek66101de2008-10-01 14:36:56 +0200375 } else {
Pekka Enberga55a89b2008-10-22 11:01:16 +0300376 if (urb)
377 usb_free_urb( urb );
Pekka Enbergf37435c2008-10-22 11:01:47 +0300378 kfree(reg_queue);
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200379 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200380 }
381}
382
383
384void
385Wb35Reg_EP0VM_start( phw_data_t pHwData )
386{
Pekka Enberg65144de2008-10-22 11:02:37 +0300387 struct wb35_reg *reg = &pHwData->reg;
Pavel Machek66101de2008-10-01 14:36:56 +0200388
Pekka Enberg44e85412008-10-29 20:10:32 +0200389 if (atomic_inc_return(&reg->RegFireCount) == 1) {
Pekka Enberg65144de2008-10-22 11:02:37 +0300390 reg->EP0vm_state = VM_RUNNING;
Pavel Machek66101de2008-10-01 14:36:56 +0200391 Wb35Reg_EP0VM(pHwData);
392 } else
Pekka Enberg44e85412008-10-29 20:10:32 +0200393 atomic_dec(&reg->RegFireCount);
Pavel Machek66101de2008-10-01 14:36:56 +0200394}
395
396void
397Wb35Reg_EP0VM(phw_data_t pHwData )
398{
Pekka Enberg65144de2008-10-22 11:02:37 +0300399 struct wb35_reg *reg = &pHwData->reg;
Pekka Enberga55a89b2008-10-22 11:01:16 +0300400 struct urb *urb;
Pavel Machek66101de2008-10-01 14:36:56 +0200401 struct usb_ctrlrequest *dr;
Pekka Enberg8b384e02008-10-21 00:03:41 +0300402 u32 * pBuffer;
Pavel Machek66101de2008-10-01 14:36:56 +0200403 int ret = -1;
Pekka Enbergf37435c2008-10-22 11:01:47 +0300404 struct wb35_reg_queue *reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200405
406
Pekka Enberg65144de2008-10-22 11:02:37 +0300407 if (reg->SyncIoPause)
Pavel Machek66101de2008-10-01 14:36:56 +0200408 goto cleanup;
409
410 if (pHwData->SurpriseRemove)
411 goto cleanup;
412
413 // Get the register data and send to USB through Irp
Pekka Enberg65144de2008-10-22 11:02:37 +0300414 spin_lock_irq( &reg->EP0VM_spin_lock );
415 reg_queue = reg->reg_first;
416 spin_unlock_irq( &reg->EP0VM_spin_lock );
Pavel Machek66101de2008-10-01 14:36:56 +0200417
Pekka Enbergf37435c2008-10-22 11:01:47 +0300418 if (!reg_queue)
Pavel Machek66101de2008-10-01 14:36:56 +0200419 goto cleanup;
420
421 // Get an Urb, send it
Pekka Enbergf37435c2008-10-22 11:01:47 +0300422 urb = (struct urb *)reg_queue->urb;
Pavel Machek66101de2008-10-01 14:36:56 +0200423
Pekka Enbergf37435c2008-10-22 11:01:47 +0300424 dr = reg_queue->pUsbReq;
425 urb = reg_queue->urb;
426 pBuffer = reg_queue->pBuffer;
427 if (reg_queue->DIRECT == 1) // output
428 pBuffer = &reg_queue->VALUE;
Pavel Machek66101de2008-10-01 14:36:56 +0200429
Pekka Enberga55a89b2008-10-22 11:01:16 +0300430 usb_fill_control_urb( urb, pHwData->WbUsb.udev,
Pekka Enbergf37435c2008-10-22 11:01:47 +0300431 REG_DIRECTION(pHwData->WbUsb.udev,reg_queue),
Pekka Enberg8b384e02008-10-21 00:03:41 +0300432 (u8 *)dr,pBuffer,cpu_to_le16(dr->wLength),
Pavel Machek66101de2008-10-01 14:36:56 +0200433 Wb35Reg_EP0VM_complete, (void*)pHwData);
434
Pekka Enberg65144de2008-10-22 11:02:37 +0300435 reg->EP0vm_state = VM_RUNNING;
Pavel Machek66101de2008-10-01 14:36:56 +0200436
Greg Kroah-Hartman7c126042008-10-27 14:21:24 -0700437 ret = usb_submit_urb(urb, GFP_ATOMIC);
Pavel Machek66101de2008-10-01 14:36:56 +0200438
439 if (ret < 0) {
440#ifdef _PE_REG_DUMP_
441 WBDEBUG(("EP0 Irp sending error\n"));
442#endif
443 goto cleanup;
444 }
445
446 return;
447
448 cleanup:
Pekka Enberg65144de2008-10-22 11:02:37 +0300449 reg->EP0vm_state = VM_STOP;
Pekka Enberg44e85412008-10-29 20:10:32 +0200450 atomic_dec(&reg->RegFireCount);
Pavel Machek66101de2008-10-01 14:36:56 +0200451}
452
453
454void
Pekka Enberga55a89b2008-10-22 11:01:16 +0300455Wb35Reg_EP0VM_complete(struct urb *urb)
Pavel Machek66101de2008-10-01 14:36:56 +0200456{
Pekka Enberga55a89b2008-10-22 11:01:16 +0300457 phw_data_t pHwData = (phw_data_t)urb->context;
Pekka Enberg65144de2008-10-22 11:02:37 +0300458 struct wb35_reg *reg = &pHwData->reg;
Pekka Enbergf37435c2008-10-22 11:01:47 +0300459 struct wb35_reg_queue *reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200460
461
462 // Variable setting
Pekka Enberg65144de2008-10-22 11:02:37 +0300463 reg->EP0vm_state = VM_COMPLETED;
464 reg->EP0VM_status = urb->status;
Pavel Machek66101de2008-10-01 14:36:56 +0200465
466 if (pHwData->SurpriseRemove) { // Let WbWlanHalt to handle surprise remove
Pekka Enberg65144de2008-10-22 11:02:37 +0300467 reg->EP0vm_state = VM_STOP;
Pekka Enberg44e85412008-10-29 20:10:32 +0200468 atomic_dec(&reg->RegFireCount);
Pavel Machek66101de2008-10-01 14:36:56 +0200469 } else {
470 // Complete to send, remove the URB from the first
Pekka Enberg65144de2008-10-22 11:02:37 +0300471 spin_lock_irq( &reg->EP0VM_spin_lock );
472 reg_queue = reg->reg_first;
473 if (reg_queue == reg->reg_last)
474 reg->reg_last = NULL;
475 reg->reg_first = reg->reg_first->Next;
476 spin_unlock_irq( &reg->EP0VM_spin_lock );
Pavel Machek66101de2008-10-01 14:36:56 +0200477
Pekka Enberg65144de2008-10-22 11:02:37 +0300478 if (reg->EP0VM_status) {
Pavel Machek66101de2008-10-01 14:36:56 +0200479#ifdef _PE_REG_DUMP_
480 WBDEBUG(("EP0 IoCompleteRoutine return error\n"));
Pekka Enberg65144de2008-10-22 11:02:37 +0300481 DebugUsbdStatusInformation( reg->EP0VM_status );
Pavel Machek66101de2008-10-01 14:36:56 +0200482#endif
Pekka Enberg65144de2008-10-22 11:02:37 +0300483 reg->EP0vm_state = VM_STOP;
Pavel Machek66101de2008-10-01 14:36:56 +0200484 pHwData->SurpriseRemove = 1;
485 } else {
486 // Success. Update the result
487
488 // Start the next send
489 Wb35Reg_EP0VM(pHwData);
490 }
491
Pekka Enbergf37435c2008-10-22 11:01:47 +0300492 kfree(reg_queue);
Pavel Machek66101de2008-10-01 14:36:56 +0200493 }
494
Pekka Enberga55a89b2008-10-22 11:01:16 +0300495 usb_free_urb(urb);
Pavel Machek66101de2008-10-01 14:36:56 +0200496}
497
498
499void
500Wb35Reg_destroy(phw_data_t pHwData)
501{
Pekka Enberg65144de2008-10-22 11:02:37 +0300502 struct wb35_reg *reg = &pHwData->reg;
Pekka Enberga55a89b2008-10-22 11:01:16 +0300503 struct urb *urb;
Pekka Enbergf37435c2008-10-22 11:01:47 +0300504 struct wb35_reg_queue *reg_queue;
Pavel Machek66101de2008-10-01 14:36:56 +0200505
506
507 Uxx_power_off_procedure(pHwData);
508
509 // Wait for Reg operation completed
510 do {
Pekka Enberg34222e02008-10-22 19:07:03 +0300511 msleep(10); // Delay for waiting function enter 940623.1.a
Pekka Enberg65144de2008-10-22 11:02:37 +0300512 } while (reg->EP0vm_state != VM_STOP);
Pekka Enberg34222e02008-10-22 19:07:03 +0300513 msleep(10); // Delay for waiting function enter 940623.1.b
Pavel Machek66101de2008-10-01 14:36:56 +0200514
515 // Release all the data in RegQueue
Pekka Enberg65144de2008-10-22 11:02:37 +0300516 spin_lock_irq(&reg->EP0VM_spin_lock);
517 reg_queue = reg->reg_first;
Pekka Enbergf37435c2008-10-22 11:01:47 +0300518 while (reg_queue) {
Pekka Enberg65144de2008-10-22 11:02:37 +0300519 if (reg_queue == reg->reg_last)
520 reg->reg_last = NULL;
521 reg->reg_first = reg->reg_first->Next;
Pavel Machek66101de2008-10-01 14:36:56 +0200522
Pekka Enbergf37435c2008-10-22 11:01:47 +0300523 urb = reg_queue->urb;
Pekka Enberg65144de2008-10-22 11:02:37 +0300524 spin_unlock_irq(&reg->EP0VM_spin_lock);
Pekka Enberga55a89b2008-10-22 11:01:16 +0300525 if (urb) {
526 usb_free_urb(urb);
Pekka Enbergf37435c2008-10-22 11:01:47 +0300527 kfree(reg_queue);
Pavel Machek66101de2008-10-01 14:36:56 +0200528 } else {
529 #ifdef _PE_REG_DUMP_
530 WBDEBUG(("EP0 queue release error\n"));
531 #endif
532 }
Pekka Enberg65144de2008-10-22 11:02:37 +0300533 spin_lock_irq( &reg->EP0VM_spin_lock );
Pavel Machek66101de2008-10-01 14:36:56 +0200534
Pekka Enberg65144de2008-10-22 11:02:37 +0300535 reg_queue = reg->reg_first;
Pavel Machek66101de2008-10-01 14:36:56 +0200536 }
Pekka Enberg65144de2008-10-22 11:02:37 +0300537 spin_unlock_irq( &reg->EP0VM_spin_lock );
Pavel Machek66101de2008-10-01 14:36:56 +0200538}
539
540//====================================================================================
541// The function can be run in passive-level only.
542//====================================================================================
543unsigned char Wb35Reg_initial(phw_data_t pHwData)
544{
Pekka Enberg65144de2008-10-22 11:02:37 +0300545 struct wb35_reg *reg=&pHwData->reg;
Pavel Machek66101de2008-10-01 14:36:56 +0200546 u32 ltmp;
547 u32 SoftwareSet, VCO_trim, TxVga, Region_ScanInterval;
548
549 // Spin lock is acquired for read and write IRP command
Pekka Enberg65144de2008-10-22 11:02:37 +0300550 spin_lock_init( &reg->EP0VM_spin_lock );
Pavel Machek66101de2008-10-01 14:36:56 +0200551
552 // Getting RF module type from EEPROM ------------------------------------
553 Wb35Reg_WriteSync( pHwData, 0x03b4, 0x080d0000 ); // Start EEPROM access + Read + address(0x0d)
554 Wb35Reg_ReadSync( pHwData, 0x03b4, &ltmp );
555
556 //Update RF module type and determine the PHY type by inf or EEPROM
Pekka Enberg65144de2008-10-22 11:02:37 +0300557 reg->EEPROMPhyType = (u8)( ltmp & 0xff );
Pavel Machek66101de2008-10-01 14:36:56 +0200558 // 0 V MAX2825, 1 V MAX2827, 2 V MAX2828, 3 V MAX2829
559 // 16V AL2230, 17 - AL7230, 18 - AL2230S
560 // 32 Reserved
561 // 33 - W89RF242(TxVGA 0~19), 34 - W89RF242(TxVGA 0~34)
Pekka Enberg65144de2008-10-22 11:02:37 +0300562 if (reg->EEPROMPhyType != RF_DECIDE_BY_INF) {
563 if( (reg->EEPROMPhyType == RF_MAXIM_2825) ||
564 (reg->EEPROMPhyType == RF_MAXIM_2827) ||
565 (reg->EEPROMPhyType == RF_MAXIM_2828) ||
566 (reg->EEPROMPhyType == RF_MAXIM_2829) ||
567 (reg->EEPROMPhyType == RF_MAXIM_V1) ||
568 (reg->EEPROMPhyType == RF_AIROHA_2230) ||
569 (reg->EEPROMPhyType == RF_AIROHA_2230S) ||
570 (reg->EEPROMPhyType == RF_AIROHA_7230) ||
571 (reg->EEPROMPhyType == RF_WB_242) ||
572 (reg->EEPROMPhyType == RF_WB_242_1))
573 pHwData->phy_type = reg->EEPROMPhyType;
Pavel Machek66101de2008-10-01 14:36:56 +0200574 }
575
576 // Power On procedure running. The relative parameter will be set according to phy_type
577 Uxx_power_on_procedure( pHwData );
578
579 // Reading MAC address
580 Uxx_ReadEthernetAddress( pHwData );
581
582 // Read VCO trim for RF parameter
583 Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08200000 );
584 Wb35Reg_ReadSync( pHwData, 0x03b4, &VCO_trim );
585
586 // Read Antenna On/Off of software flag
587 Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08210000 );
588 Wb35Reg_ReadSync( pHwData, 0x03b4, &SoftwareSet );
589
590 // Read TXVGA
591 Wb35Reg_WriteSync( pHwData, 0x03b4, 0x08100000 );
592 Wb35Reg_ReadSync( pHwData, 0x03b4, &TxVga );
593
594 // Get Scan interval setting from EEPROM offset 0x1c
595 Wb35Reg_WriteSync( pHwData, 0x03b4, 0x081d0000 );
596 Wb35Reg_ReadSync( pHwData, 0x03b4, &Region_ScanInterval );
597
598 // Update Ethernet address
599 memcpy( pHwData->CurrentMacAddress, pHwData->PermanentMacAddress, ETH_LENGTH_OF_ADDRESS );
600
601 // Update software variable
602 pHwData->SoftwareSet = (u16)(SoftwareSet & 0xffff);
603 TxVga &= 0x000000ff;
604 pHwData->PowerIndexFromEEPROM = (u8)TxVga;
605 pHwData->VCO_trim = (u8)VCO_trim & 0xff;
606 if (pHwData->VCO_trim == 0xff)
607 pHwData->VCO_trim = 0x28;
608
Pekka Enberg65144de2008-10-22 11:02:37 +0300609 reg->EEPROMRegion = (u8)(Region_ScanInterval>>8); // 20060720
610 if( reg->EEPROMRegion<1 || reg->EEPROMRegion>6 )
611 reg->EEPROMRegion = REGION_AUTO;
Pavel Machek66101de2008-10-01 14:36:56 +0200612
613 //For Get Tx VGA from EEPROM 20060315.5 move here
614 GetTxVgaFromEEPROM( pHwData );
615
616 // Set Scan Interval
617 pHwData->Scan_Interval = (u8)(Region_ScanInterval & 0xff) * 10;
618 if ((pHwData->Scan_Interval == 2550) || (pHwData->Scan_Interval < 10)) // Is default setting 0xff * 10
619 pHwData->Scan_Interval = SCAN_MAX_CHNL_TIME;
620
621 // Initial register
622 RFSynthesizer_initial(pHwData);
623
624 BBProcessor_initial(pHwData); // Async write, must wait until complete
625
626 Wb35Reg_phy_calibration(pHwData);
627
628 Mxx_initial(pHwData);
629 Dxx_initial(pHwData);
630
631 if (pHwData->SurpriseRemove)
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200632 return false;
Pavel Machek66101de2008-10-01 14:36:56 +0200633 else
Pekka Enberg279b6cc2008-10-27 22:46:39 +0200634 return true; // Initial fail
Pavel Machek66101de2008-10-01 14:36:56 +0200635}
636
637//===================================================================================
638// CardComputeCrc --
639//
640// Description:
641// Runs the AUTODIN II CRC algorithm on buffer Buffer of length, Length.
642//
643// Arguments:
644// Buffer - the input buffer
645// Length - the length of Buffer
646//
647// Return Value:
648// The 32-bit CRC value.
649//
650// Note:
651// This is adapted from the comments in the assembly language
652// version in _GENREQ.ASM of the DWB NE1000/2000 driver.
653//==================================================================================
654u32
Pekka Enberg8b384e02008-10-21 00:03:41 +0300655CardComputeCrc(u8 * Buffer, u32 Length)
Pavel Machek66101de2008-10-01 14:36:56 +0200656{
657 u32 Crc, Carry;
658 u32 i, j;
659 u8 CurByte;
660
661 Crc = 0xffffffff;
662
663 for (i = 0; i < Length; i++) {
664
665 CurByte = Buffer[i];
666
667 for (j = 0; j < 8; j++) {
668
669 Carry = ((Crc & 0x80000000) ? 1 : 0) ^ (CurByte & 0x01);
670 Crc <<= 1;
671 CurByte >>= 1;
672
673 if (Carry) {
674 Crc =(Crc ^ 0x04c11db6) | Carry;
675 }
676 }
677 }
678
679 return Crc;
680}
681
682
683//==================================================================
684// BitReverse --
685// Reverse the bits in the input argument, dwData, which is
686// regarded as a string of bits with the length, DataLength.
687//
688// Arguments:
689// dwData :
690// DataLength :
691//
692// Return:
693// The converted value.
694//==================================================================
695u32 BitReverse( u32 dwData, u32 DataLength)
696{
697 u32 HalfLength, i, j;
698 u32 BitA, BitB;
699
700 if ( DataLength <= 0) return 0; // No conversion is done.
701 dwData = dwData & (0xffffffff >> (32 - DataLength));
702
703 HalfLength = DataLength / 2;
704 for ( i = 0, j = DataLength-1 ; i < HalfLength; i++, j--)
705 {
706 BitA = GetBit( dwData, i);
707 BitB = GetBit( dwData, j);
708 if (BitA && !BitB) {
709 dwData = ClearBit( dwData, i);
710 dwData = SetBit( dwData, j);
711 } else if (!BitA && BitB) {
712 dwData = SetBit( dwData, i);
713 dwData = ClearBit( dwData, j);
714 } else
715 {
716 // Do nothing since these two bits are of the save values.
717 }
718 }
719
720 return dwData;
721}
722
723void Wb35Reg_phy_calibration( phw_data_t pHwData )
724{
725 u32 BB3c, BB54;
726
727 if ((pHwData->phy_type == RF_WB_242) ||
728 (pHwData->phy_type == RF_WB_242_1)) {
729 phy_calibration_winbond ( pHwData, 2412 ); // Sync operation
730 Wb35Reg_ReadSync( pHwData, 0x103c, &BB3c );
731 Wb35Reg_ReadSync( pHwData, 0x1054, &BB54 );
732
733 pHwData->BB3c_cal = BB3c;
734 pHwData->BB54_cal = BB54;
735
736 RFSynthesizer_initial(pHwData);
737 BBProcessor_initial(pHwData); // Async operation
738
739 Wb35Reg_WriteSync( pHwData, 0x103c, BB3c );
740 Wb35Reg_WriteSync( pHwData, 0x1054, BB54 );
741 }
742}
743
744