118 if ( iTxFrameMemoryPool && iTxFrameMemoryPool->IsValid() ) |
118 if ( iTxFrameMemoryPool && iTxFrameMemoryPool->IsValid() ) |
119 { |
119 { |
120 TraceDump(MEMORY, (("WLANLDD: new WlanChunk: 0x%08x"), |
120 TraceDump(MEMORY, (("WLANLDD: new WlanChunk: 0x%08x"), |
121 reinterpret_cast<TUint32>(iTxFrameMemoryPool))); |
121 reinterpret_cast<TUint32>(iTxFrameMemoryPool))); |
122 |
122 |
123 iFrameXferBlock = reinterpret_cast<RFrameXferBlock*>( |
|
124 start_of_mem |
|
125 + KRxDataChunkSize |
|
126 + sizeof( TDataBuffer ) |
|
127 + KMgmtSideTxBufferLength |
|
128 + KProtocolStackSideTxDataChunkSize |
|
129 + sizeof( RFrameXferBlock ) ); |
|
130 |
|
131 iFrameXferBlockProtoStack = |
123 iFrameXferBlockProtoStack = |
132 static_cast<RFrameXferBlockProtocolStack*>(iFrameXferBlock); |
124 reinterpret_cast<RFrameXferBlockProtocolStack*>( |
|
125 start_of_mem |
|
126 + KRxDataChunkSize |
|
127 + sizeof( TDataBuffer ) |
|
128 + KMgmtSideTxBufferLength |
|
129 + KProtocolStackSideTxDataChunkSize |
|
130 + sizeof( RFrameXferBlock ) ); |
|
131 |
|
132 iFrameXferBlockBase = iFrameXferBlockProtoStack; |
133 |
133 |
134 TraceDump( INIT_LEVEL, |
134 TraceDump( INIT_LEVEL, |
135 (("WLANLDD: DataFrameMemMngr::DoOpenHandle: Nif RFrameXferBlock addr: 0x%08x"), |
135 (("WLANLDD: DataFrameMemMngr::DoOpenHandle: Nif RFrameXferBlock addr: 0x%08x"), |
136 reinterpret_cast<TUint32>(iFrameXferBlockProtoStack) ) ); |
136 reinterpret_cast<TUint32>(iFrameXferBlockProtoStack) ) ); |
137 |
137 |
138 // initiliase xfer block |
138 // initiliase xfer block |
139 iFrameXferBlockProtoStack->Initialise(); |
139 iFrameXferBlockProtoStack->Initialize(); |
140 |
140 |
141 iRxBufAlignmentPadding = iParent.RxBufAlignmentPadding(); |
141 iRxBufAlignmentPadding = iParent.RxBufAlignmentPadding(); |
142 |
142 |
143 ret = KErrNone; |
143 ret = KErrNone; |
144 } |
144 } |
173 |
173 |
174 // --------------------------------------------------------------------------- |
174 // --------------------------------------------------------------------------- |
175 // |
175 // |
176 // --------------------------------------------------------------------------- |
176 // --------------------------------------------------------------------------- |
177 // |
177 // |
178 void DataFrameMemMngr::DoFreeRxBuffers() |
178 TBool DataFrameMemMngr::DoEthernetFrameRxComplete( |
179 { |
179 TDataBuffer*& aBufferStart, |
180 for ( TUint i = 0; i < iCountCompleted; ++i ) |
180 TUint32 aNumOfBuffers ) |
181 { |
181 { |
182 TDataBuffer* metaHdr ( reinterpret_cast<TDataBuffer*>( |
182 TraceDump( RX_FRAME, |
183 iRxDataChunk + iCompletedBuffers[i]) ); |
183 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: " |
184 |
184 "aNumOfBuffers: %d"), |
185 // first free the actual Rx frame buffer if relevant |
185 aNumOfBuffers) ); |
186 if ( metaHdr->KeFlags() & TDataBuffer::KDontReleaseBuffer ) |
186 |
187 { |
187 TBool ret( EFalse ); |
188 // this buffer shall not be freed yet, so no action here |
188 TDataBuffer** metaHdrPtrArray(&aBufferStart); |
|
189 |
|
190 if ( iFrameXferBlockProtoStack ) |
|
191 { |
|
192 for ( TUint i = 0; i < aNumOfBuffers; ++i ) |
|
193 { |
|
194 if ( metaHdrPtrArray[i] ) |
|
195 { |
|
196 iFrameXferBlockProtoStack->AddRxFrame( metaHdrPtrArray[i] ); |
|
197 } |
|
198 } |
|
199 |
|
200 if ( iReadStatus == EPending ) |
|
201 { |
|
202 ret = ETrue; |
|
203 } |
|
204 } |
|
205 |
|
206 return ret; |
|
207 } |
|
208 |
|
209 // --------------------------------------------------------------------------- |
|
210 // |
|
211 // --------------------------------------------------------------------------- |
|
212 // |
|
213 TBool DataFrameMemMngr::OnReadRequest() |
|
214 { |
|
215 TBool ret( EFalse ); |
|
216 |
|
217 if ( IsMemInUse() && iFrameXferBlockProtoStack ) |
|
218 { |
|
219 if ( iFrameXferBlockProtoStack->RxFrameAvailable() ) |
|
220 { |
|
221 // there are Rx frames ready for the user mode client retrieval |
|
222 ret = ETrue; |
189 |
223 |
190 TraceDump( RX_FRAME, |
224 // the frame Rx request won't be left pending as the callee will |
191 (("WLANLDD: DataFrameMemMngr::DoFreeRxBuffers: don't free yet Rx buf at addr: 0x%08x"), |
225 // complete it |
192 reinterpret_cast<TUint32>(metaHdr->KeGetBufferStart()) ) ); |
226 iReadStatus = ENotPending; |
193 } |
227 } |
194 else |
228 else |
195 { |
229 { |
196 TraceDump( RX_FRAME, |
230 // there are no Rx frames ready for the user mode client retrieval |
197 (("WLANLDD: DataFrameMemMngr::DoFreeRxBuffers: free Rx buf at addr: 0x%08x"), |
231 // the Rx request is left pending |
198 reinterpret_cast<TUint32>(metaHdr->KeGetBufferStart()) ) ); |
232 iReadStatus = EPending; |
199 |
233 } |
200 iRxFrameMemoryPool->Free( |
234 } |
201 metaHdr->KeGetBufferStart() |
235 #ifndef NDEBUG |
202 // take into account the alignment padding |
236 else |
203 - iRxBufAlignmentPadding ); |
237 { |
204 } |
238 os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ ); |
205 |
239 } |
206 // free the Rx frame meta header |
240 #endif |
207 |
241 |
208 TraceDump( RX_FRAME, |
|
209 (("WLANLDD: DataFrameMemMngr::DoFreeRxBuffers: free Rx meta header at addr: 0x%08x"), |
|
210 reinterpret_cast<TUint32>(metaHdr)) ); |
|
211 |
|
212 iRxFrameMemoryPool->Free( metaHdr ); |
|
213 } |
|
214 } |
|
215 |
|
216 // --------------------------------------------------------------------------- |
|
217 // |
|
218 // --------------------------------------------------------------------------- |
|
219 // |
|
220 TBool DataFrameMemMngr::DoEthernetFrameRxComplete( |
|
221 const TDataBuffer*& aBufferStart, |
|
222 TUint32 aNumOfBuffers ) |
|
223 { |
|
224 TraceDump( RX_FRAME, |
242 TraceDump( RX_FRAME, |
225 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: aNumOfBuffers: %d"), |
243 (("WLANLDD: DataFrameMemMngr::OnReadRequest: ret (bool): %d"), |
226 aNumOfBuffers) ); |
244 ret) ); |
227 |
|
228 if ( aNumOfBuffers + iCountTobeCompleted > KMaxToBeCompletedRxBufs ) |
|
229 { |
|
230 // too little space reserved for Rx buffer handles |
|
231 os_assert( (TUint8*)("WLANLDD: panic"), (TUint8*)(WLAN_FILE), __LINE__ ); |
|
232 } |
|
233 |
|
234 TBool ret( EFalse ); |
|
235 |
|
236 if ( iReadStatus == EPending ) |
|
237 { |
|
238 // read pending |
|
239 if ( !iCountTobeCompleted ) |
|
240 { |
|
241 // no existing Rx buffers to complete in queue |
|
242 // we may complete these ones on the fly |
|
243 |
|
244 // note the completed Rx buffers first so that we can change |
|
245 // their addresses to offsets |
|
246 assign( |
|
247 reinterpret_cast<TUint32*>(&aBufferStart), |
|
248 iCompletedBuffers, |
|
249 aNumOfBuffers ); |
|
250 |
|
251 // update the new Rx buffer start addresses added above to be |
|
252 // offsets from the Rx memory pool beginning |
|
253 for( TUint i = 0; i < aNumOfBuffers; ++i ) |
|
254 { |
|
255 TraceDump( RX_FRAME, |
|
256 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: supplied Rx buf addr: 0x%08x"), |
|
257 iCompletedBuffers[i]) ); |
|
258 |
|
259 iCompletedBuffers[i] |
|
260 -= reinterpret_cast<TUint32>(iRxDataChunk); |
|
261 |
|
262 TraceDump( RX_FRAME, |
|
263 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: Rx buf offset addr: 0x%08x"), |
|
264 iCompletedBuffers[i]) ); |
|
265 } |
|
266 |
|
267 iCountCompleted = aNumOfBuffers; |
|
268 |
|
269 iFrameXferBlock->KeRxComplete( iCompletedBuffers, iCountCompleted); |
|
270 } |
|
271 else |
|
272 { |
|
273 // existing rx buffers to complete in queue. |
|
274 // We must append these at the rear and after that |
|
275 // complete the existing read request |
|
276 assign( |
|
277 reinterpret_cast<TUint32*>(&aBufferStart), |
|
278 iTobeCompletedBuffers + iCountTobeCompleted, |
|
279 aNumOfBuffers ); |
|
280 |
|
281 // update the new Rx buffer start addresses added above to be |
|
282 // offsets from the Rx memory pool beginning |
|
283 for( TUint i = 0; i < aNumOfBuffers; ++i ) |
|
284 { |
|
285 TraceDump( RX_FRAME, |
|
286 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: supplied Rx buf addr: 0x%08x"), |
|
287 iTobeCompletedBuffers[iCountTobeCompleted + i]) ); |
|
288 |
|
289 iTobeCompletedBuffers[iCountTobeCompleted + i] |
|
290 -= reinterpret_cast<TUint32>(iRxDataChunk); |
|
291 |
|
292 TraceDump( RX_FRAME, |
|
293 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: Rx buf offset addr: 0x%08x"), |
|
294 iTobeCompletedBuffers[iCountTobeCompleted + i]) ); |
|
295 } |
|
296 |
|
297 iCountCompleted = iCountTobeCompleted + aNumOfBuffers; |
|
298 |
|
299 iFrameXferBlock->KeRxComplete( |
|
300 iTobeCompletedBuffers, |
|
301 iCountCompleted ); |
|
302 |
|
303 // note the completed Rx buffers |
|
304 assign( iTobeCompletedBuffers, iCompletedBuffers, iCountCompleted ); |
|
305 iCountTobeCompleted = 0; |
|
306 } |
|
307 |
|
308 ret = ETrue; |
|
309 } |
|
310 else |
|
311 { |
|
312 // no read pending |
|
313 // append at the rear |
|
314 assign( |
|
315 reinterpret_cast<TUint32*>(&aBufferStart), |
|
316 iTobeCompletedBuffers + iCountTobeCompleted, |
|
317 aNumOfBuffers ); |
|
318 |
|
319 // update the new Rx buffer start addresses added above to be |
|
320 // offsets from the Rx memory pool beginning |
|
321 for( TUint i = 0; i < aNumOfBuffers; ++i ) |
|
322 { |
|
323 TraceDump( RX_FRAME, |
|
324 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: supplied Rx buf addr: 0x%08x"), |
|
325 iTobeCompletedBuffers[iCountTobeCompleted + i]) ); |
|
326 |
|
327 iTobeCompletedBuffers[iCountTobeCompleted + i] |
|
328 -= reinterpret_cast<TUint32>(iRxDataChunk); |
|
329 |
|
330 TraceDump( RX_FRAME, |
|
331 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: Rx buf offset addr: 0x%08x"), |
|
332 iTobeCompletedBuffers[iCountTobeCompleted + i]) ); |
|
333 } |
|
334 |
|
335 iCountTobeCompleted += aNumOfBuffers; |
|
336 } |
|
337 |
|
338 TraceDump( RX_FRAME, |
|
339 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: end: iCountCompleted: %d"), |
|
340 iCountCompleted) ); |
|
341 |
|
342 TraceDump( RX_FRAME, |
|
343 (("WLANLDD: DataFrameMemMngr::DoEthernetFrameRxComplete: end: iCountTobeCompleted: %d"), |
|
344 iCountTobeCompleted) ); |
|
345 |
245 |
346 return ret; |
246 return ret; |
347 } |
247 } |
348 |
248 |
349 // --------------------------------------------------------------------------- |
249 // --------------------------------------------------------------------------- |
350 // |
250 // Note! This method is executed in the context of the user mode client |
351 // --------------------------------------------------------------------------- |
251 // thread, but in supervisor mode |
352 // |
252 // --------------------------------------------------------------------------- |
353 TUint32* DataFrameMemMngr::DoGetTobeCompletedBuffersStart() |
253 // |
354 { |
254 TDataBuffer* DataFrameMemMngr::GetRxFrame( |
355 return iTobeCompletedBuffers; |
255 TDataBuffer* aFrameToFreeInUserSpace ) |
356 } |
256 { |
357 |
257 TDataBuffer* rxFrame( NULL ); |
358 // --------------------------------------------------------------------------- |
258 |
359 // |
259 if ( IsMemInUse() && iFrameXferBlockProtoStack ) |
360 // --------------------------------------------------------------------------- |
260 { |
361 // |
261 if ( aFrameToFreeInUserSpace ) |
362 TUint32* DataFrameMemMngr::DoGetCompletedBuffersStart() |
262 { |
363 { |
263 FreeRxPacket( aFrameToFreeInUserSpace ); |
364 return iCompletedBuffers; |
264 } |
365 } |
265 |
366 |
266 rxFrame = iFrameXferBlockProtoStack->GetRxFrame(); |
367 // --------------------------------------------------------------------------- |
267 } |
368 // |
268 |
|
269 return rxFrame; |
|
270 } |
|
271 |
|
272 // --------------------------------------------------------------------------- |
|
273 // Note! This method is executed in the context of the user mode client |
|
274 // thread, but in supervisor mode |
369 // --------------------------------------------------------------------------- |
275 // --------------------------------------------------------------------------- |
370 // |
276 // |
371 TDataBuffer* DataFrameMemMngr::AllocTxBuffer( TUint aLength ) |
277 TDataBuffer* DataFrameMemMngr::AllocTxBuffer( TUint aLength ) |
372 { |
278 { |
373 TraceDump( NWSA_TX_DETAILS, |
279 TraceDump( NWSA_TX_DETAILS, |
374 (("WLANLDD: DataFrameMemMngr::AllocTxBuffer: aLength: %d"), |
280 (("WLANLDD: DataFrameMemMngr::AllocTxBuffer: aLength: %d"), |
375 aLength) ); |
281 aLength) ); |
376 |
282 |
377 TDataBuffer* metaHdr ( NULL ); |
283 TDataBuffer* metaHdr ( NULL ); |
378 |
284 |
379 if ( ( !IsMemInUse() ) || ( aLength > KMaxEthernetFrameLength ) ) |
285 if ( ( !IsMemInUse() ) || |
|
286 ( !iTxFrameMemoryPool ) || |
|
287 ( !iFrameXferBlockProtoStack ) || |
|
288 ( aLength > KMaxEthernetFrameLength ) ) |
380 { |
289 { |
381 #ifndef NDEBUG |
290 #ifndef NDEBUG |
382 TraceDump( NWSA_TX_DETAILS, |
291 TraceDump( NWSA_TX_DETAILS, |
383 ("WLANLDD: DataFrameMemMngr::AllocTxBuffer: WARNING: either " |
292 ("WLANLDD: DataFrameMemMngr::AllocTxBuffer: WARNING: either " |
384 "memory not in use OR max size exceeded. Req. denied") ); |
293 "memory not in use OR max size exceeded. Req. denied") ); |
421 |
330 |
422 return metaHdr; |
331 return metaHdr; |
423 } |
332 } |
424 |
333 |
425 // --------------------------------------------------------------------------- |
334 // --------------------------------------------------------------------------- |
|
335 // Note! This method is executed in the context of the user mode client |
|
336 // thread, but in supervisor mode |
|
337 // --------------------------------------------------------------------------- |
|
338 // |
|
339 TBool DataFrameMemMngr::AddTxFrame( |
|
340 TDataBuffer* aPacketInUserSpace, |
|
341 TDataBuffer*& aPacketInKernSpace, |
|
342 TBool aUserDataTxEnabled ) |
|
343 { |
|
344 if ( IsMemInUse() && iFrameXferBlockProtoStack ) |
|
345 { |
|
346 return iFrameXferBlockProtoStack->AddTxFrame( |
|
347 aPacketInUserSpace, |
|
348 aPacketInKernSpace, |
|
349 aUserDataTxEnabled ); |
|
350 } |
|
351 else |
|
352 { |
|
353 return EFalse; |
|
354 } |
|
355 } |
|
356 |
|
357 // --------------------------------------------------------------------------- |
426 // |
358 // |
427 // --------------------------------------------------------------------------- |
359 // --------------------------------------------------------------------------- |
428 // |
360 // |
|
361 TDataBuffer* DataFrameMemMngr::GetTxFrame( |
|
362 const TWhaTxQueueState& aTxQueueState, |
|
363 TBool& aMore ) |
|
364 { |
|
365 if ( IsMemInUse() && iFrameXferBlockProtoStack ) |
|
366 { |
|
367 return iFrameXferBlockProtoStack->GetTxFrame( aTxQueueState, aMore ); |
|
368 } |
|
369 else |
|
370 { |
|
371 return NULL; |
|
372 } |
|
373 } |
|
374 |
|
375 // --------------------------------------------------------------------------- |
|
376 // Note! This method is executed also in the context of the user mode client |
|
377 // thread, but in supervisor mode |
|
378 // --------------------------------------------------------------------------- |
|
379 // |
429 void DataFrameMemMngr::FreeTxPacket( TDataBuffer*& aPacket ) |
380 void DataFrameMemMngr::FreeTxPacket( TDataBuffer*& aPacket ) |
430 { |
381 { |
431 if ( IsMemInUse() ) |
382 if ( aPacket ) |
432 { |
383 { |
433 // free the actual Tx buffer |
384 if ( iTxFrameMemoryPool ) |
434 iTxFrameMemoryPool->Free( aPacket->KeGetBufferStart() ); |
385 { |
435 // free the meta header |
386 // free the actual Tx buffer |
436 iFrameXferBlockProtoStack->FreeTxPacket( aPacket ); |
387 iTxFrameMemoryPool->Free( aPacket->KeGetBufferStart() ); |
437 } |
388 } |
|
389 |
|
390 if ( iFrameXferBlockProtoStack ) |
|
391 { |
|
392 // free the meta header |
|
393 iFrameXferBlockProtoStack->FreeTxPacket( aPacket ); |
|
394 } |
|
395 } |
|
396 } |
|
397 |
|
398 // --------------------------------------------------------------------------- |
|
399 // |
|
400 // --------------------------------------------------------------------------- |
|
401 // |
|
402 TBool DataFrameMemMngr::ResumeClientTx( TBool aUserDataTxEnabled ) const |
|
403 { |
|
404 TBool ret( EFalse ); |
|
405 |
|
406 if ( iFrameXferBlockProtoStack ) |
|
407 { |
|
408 ret = iFrameXferBlockProtoStack->ResumeClientTx( aUserDataTxEnabled ); |
|
409 } |
|
410 |
|
411 return ret; |
|
412 } |
|
413 |
|
414 // --------------------------------------------------------------------------- |
|
415 // Note! This method is executed in the context of the user mode client |
|
416 // thread, but in supervisor mode |
|
417 // --------------------------------------------------------------------------- |
|
418 // |
|
419 TBool DataFrameMemMngr::AllTxQueuesEmpty() const |
|
420 { |
|
421 TBool ret( EFalse ); |
|
422 |
|
423 if ( iFrameXferBlockProtoStack ) |
|
424 { |
|
425 ret = iFrameXferBlockProtoStack->AllTxQueuesEmpty(); |
|
426 } |
|
427 |
|
428 return ret; |
438 } |
429 } |
439 |
430 |
440 // --------------------------------------------------------------------------- |
431 // --------------------------------------------------------------------------- |
441 // |
432 // |
442 // --------------------------------------------------------------------------- |
433 // --------------------------------------------------------------------------- |