r819xU_cmdpkt.c revision fa6b108bb17558d721c5adfa48fc309388cd0230
1/****************************************************************************** 2 3 (c) Copyright 2008, RealTEK Technologies Inc. All Rights Reserved. 4 5 Module: r819xusb_cmdpkt.c (RTL8190 TX/RX command packet handler Source C File) 6 7 Note: The module is responsible for handling TX and RX command packet. 8 1. TX : Send set and query configuration command packet. 9 2. RX : Receive tx feedback, beacon state, query configuration 10 command packet. 11 12 Function: 13 14 Export: 15 16 Abbrev: 17 18 History: 19 Data Who Remark 20 21 05/06/2008 amy Create initial version porting from windows driver. 22 23******************************************************************************/ 24#include "r8192U.h" 25#include "r819xU_cmdpkt.h" 26/*---------------------------Define Local Constant---------------------------*/ 27/* Debug constant*/ 28#define CMPK_DEBOUNCE_CNT 1 29/* 2007/10/24 MH Add for printing a range of data. */ 30#define CMPK_PRINT(Address)\ 31{\ 32 unsigned char i;\ 33 u32 temp[10];\ 34 \ 35 memcpy(temp, Address, 40);\ 36 for (i = 0; i < 40; i += 4)\ 37 printk("\r\n %08x", temp[i]);\ 38}\ 39/*---------------------------Define functions---------------------------------*/ 40 41rt_status SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen) 42{ 43 rt_status rtStatus = RT_STATUS_SUCCESS; 44 struct r8192_priv *priv = ieee80211_priv(dev); 45 struct sk_buff *skb; 46 cb_desc *tcb_desc; 47 unsigned char *ptr_buf; 48 49 //Get TCB and local buffer from common pool. (It is shared by CmdQ, MgntQ, and USB coalesce DataQ) 50 skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4); 51 memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); 52 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); 53 tcb_desc->queue_index = TXCMD_QUEUE; 54 tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL; 55 tcb_desc->bLastIniPkt = 0; 56 skb_reserve(skb, USB_HWDESC_HEADER_LEN); 57 ptr_buf = skb_put(skb, DataLen); 58 memcpy(ptr_buf, pData, DataLen); 59 tcb_desc->txbuf_size = (u16)DataLen; 60 61 if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) || 62 (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||\ 63 (priv->ieee80211->queue_stop)) { 64 RT_TRACE(COMP_FIRMWARE, "===================NULL packet==================================> tx full!\n"); 65 skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); 66 } else { 67 priv->ieee80211->softmac_hard_start_xmit(skb, dev); 68 } 69 70 return rtStatus; 71} 72 73/*----------------------------------------------------------------------------- 74 * Function: cmpk_message_handle_tx() 75 * 76 * Overview: Driver internal module can call the API to send message to 77 * firmware side. For example, you can send a debug command packet. 78 * Or you can send a request for FW to modify RLX4181 LBUS HW bank. 79 * Otherwise, you can change MAC/PHT/RF register by firmware at 80 * run time. We do not support message more than one segment now. 81 * 82 * Input: NONE 83 * 84 * Output: NONE 85 * 86 * Return: NONE 87 * 88 * Revised History: 89 * When Who Remark 90 * 05/06/2008 amy porting from windows code. 91 * 92 *---------------------------------------------------------------------------*/ 93extern rt_status cmpk_message_handle_tx(struct net_device *dev, 94 u8 *codevirtualaddress, 95 u32 packettype, u32 buffer_len) 96{ 97 98 bool rt_status = true; 99#ifdef RTL8192U 100 return rt_status; 101#else 102 struct r8192_priv *priv = ieee80211_priv(dev); 103 u16 frag_threshold; 104 u16 frag_length, frag_offset = 0; 105 106 rt_firmware *pfirmware = priv->pFirmware; 107 struct sk_buff *skb; 108 unsigned char *seg_ptr; 109 cb_desc *tcb_desc; 110 u8 bLastIniPkt; 111 112 firmware_init_param(dev); 113 //Fragmentation might be required 114 frag_threshold = pfirmware->cmdpacket_frag_thresold; 115 do { 116 if ((buffer_len - frag_offset) > frag_threshold) { 117 frag_length = frag_threshold; 118 bLastIniPkt = 0; 119 120 } else { 121 frag_length = buffer_len - frag_offset; 122 bLastIniPkt = 1; 123 124 } 125 126 /* Allocate skb buffer to contain firmware info and tx descriptor info 127 * add 4 to avoid packet appending overflow. 128 * */ 129 #ifdef RTL8192U 130 skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + frag_length + 4); 131 #else 132 skb = dev_alloc_skb(frag_length + 4); 133 #endif 134 memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev)); 135 tcb_desc = (cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE); 136 tcb_desc->queue_index = TXCMD_QUEUE; 137 tcb_desc->bCmdOrInit = packettype; 138 tcb_desc->bLastIniPkt = bLastIniPkt; 139 140 #ifdef RTL8192U 141 skb_reserve(skb, USB_HWDESC_HEADER_LEN); 142 #endif 143 144 seg_ptr = skb_put(skb, buffer_len); 145 /* 146 * Transform from little endian to big endian 147 * and pending zero 148 */ 149 memcpy(seg_ptr, codevirtualaddress, buffer_len); 150 tcb_desc->txbuf_size = (u16)buffer_len; 151 152 153 if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) || 154 (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||\ 155 (priv->ieee80211->queue_stop)) { 156 RT_TRACE(COMP_FIRMWARE, "=====================================================> tx full!\n"); 157 skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb); 158 } else { 159 priv->ieee80211->softmac_hard_start_xmit(skb, dev); 160 } 161 162 codevirtualaddress += frag_length; 163 frag_offset += frag_length; 164 165 } while (frag_offset < buffer_len); 166 167 return rt_status; 168 169 170#endif 171} /* CMPK_Message_Handle_Tx */ 172 173/*----------------------------------------------------------------------------- 174 * Function: cmpk_counttxstatistic() 175 * 176 * Overview: 177 * 178 * Input: PADAPTER pAdapter - . 179 * CMPK_TXFB_T *psTx_FB - . 180 * 181 * Output: NONE 182 * 183 * Return: NONE 184 * 185 * Revised History: 186 * When Who Remark 187 * 05/12/2008 amy Create Version 0 porting from windows code. 188 * 189 *---------------------------------------------------------------------------*/ 190static void cmpk_count_txstatistic(struct net_device *dev, cmpk_txfb_t *pstx_fb) 191{ 192 struct r8192_priv *priv = ieee80211_priv(dev); 193#ifdef ENABLE_PS 194 RT_RF_POWER_STATE rtState; 195 196 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); 197 198 // When RF is off, we should not count the packet for hw/sw synchronize 199 // reason, ie. there may be a duration while sw switch is changed and hw 200 // switch is being changed. 2006.12.04, by shien chang. 201 if (rtState == eRfOff) 202 return; 203#endif 204 205#ifdef TODO 206 if (pAdapter->bInHctTest) 207 return; 208#endif 209 /* We can not know the packet length and transmit type: broadcast or uni 210 or multicast. So the relative statistics must be collected in tx 211 feedback info. */ 212 if (pstx_fb->tok) { 213 priv->stats.txfeedbackok++; 214 priv->stats.txoktotal++; 215 priv->stats.txokbytestotal += pstx_fb->pkt_length; 216 priv->stats.txokinperiod++; 217 218 /* We can not make sure broadcast/multicast or unicast mode. */ 219 if (pstx_fb->pkt_type == PACKET_MULTICAST) { 220 priv->stats.txmulticast++; 221 priv->stats.txbytesmulticast += pstx_fb->pkt_length; 222 } else if (pstx_fb->pkt_type == PACKET_BROADCAST) { 223 priv->stats.txbroadcast++; 224 priv->stats.txbytesbroadcast += pstx_fb->pkt_length; 225 } else { 226 priv->stats.txunicast++; 227 priv->stats.txbytesunicast += pstx_fb->pkt_length; 228 } 229 } else { 230 priv->stats.txfeedbackfail++; 231 priv->stats.txerrtotal++; 232 priv->stats.txerrbytestotal += pstx_fb->pkt_length; 233 234 /* We can not make sure broadcast/multicast or unicast mode. */ 235 if (pstx_fb->pkt_type == PACKET_MULTICAST) 236 priv->stats.txerrmulticast++; 237 else if (pstx_fb->pkt_type == PACKET_BROADCAST) 238 priv->stats.txerrbroadcast++; 239 else 240 priv->stats.txerrunicast++; 241 } 242 243 priv->stats.txretrycount += pstx_fb->retry_cnt; 244 priv->stats.txfeedbackretry += pstx_fb->retry_cnt; 245 246} /* cmpk_CountTxStatistic */ 247 248 249 250/*----------------------------------------------------------------------------- 251 * Function: cmpk_handle_tx_feedback() 252 * 253 * Overview: The function is responsible for extract the message inside TX 254 * feedbck message from firmware. It will contain dedicated info in 255 * ws-06-0063-rtl8190-command-packet-specification. Please 256 * refer to chapter "TX Feedback Element". We have to read 20 bytes 257 * in the command packet. 258 * 259 * Input: struct net_device * dev 260 * u8 * pmsg - Msg Ptr of the command packet. 261 * 262 * Output: NONE 263 * 264 * Return: NONE 265 * 266 * Revised History: 267 * When Who Remark 268 * 05/08/2008 amy Create Version 0 porting from windows code. 269 * 270 *---------------------------------------------------------------------------*/ 271static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg) 272{ 273 struct r8192_priv *priv = ieee80211_priv(dev); 274 cmpk_txfb_t rx_tx_fb; /* */ 275 276 priv->stats.txfeedback++; 277 278 /* 1. Extract TX feedback info from RFD to temp structure buffer. */ 279 /* It seems that FW use big endian(MIPS) and DRV use little endian in 280 windows OS. So we have to read the content byte by byte or transfer 281 endian type before copy the message copy. */ 282 /* 2007/07/05 MH Use pointer to transfer structure memory. */ 283 memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(cmpk_txfb_t)); 284 /* 2. Use tx feedback info to count TX statistics. */ 285 cmpk_count_txstatistic(dev, &rx_tx_fb); 286 /* 2007/01/17 MH Comment previous method for TX statistic function. */ 287 /* Collect info TX feedback packet to fill TCB. */ 288 /* We can not know the packet length and transmit type: broadcast or uni 289 or multicast. */ 290 291} /* cmpk_Handle_Tx_Feedback */ 292 293void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev) 294{ 295 struct r8192_priv *priv = ieee80211_priv(dev); 296 u16 tx_rate; 297 // 298 // 070117, rcnjko: 87B have to S/W beacon for DTM encryption_cmn. 299 // 300 if (priv->ieee80211->current_network.mode == IEEE_A || 301 priv->ieee80211->current_network.mode == IEEE_N_5G || 302 (priv->ieee80211->current_network.mode == IEEE_N_24G && (!priv->ieee80211->pHTInfo->bCurSuppCCK))) { 303 tx_rate = 60; 304 DMESG("send beacon frame tx rate is 6Mbpm\n"); 305 } else { 306 tx_rate = 10; 307 DMESG("send beacon frame tx rate is 1Mbpm\n"); 308 } 309 310 rtl819xusb_beacon_tx(dev, tx_rate); // HW Beacon 311 312 313} 314 315 316 317 318/*----------------------------------------------------------------------------- 319 * Function: cmpk_handle_interrupt_status() 320 * 321 * Overview: The function is responsible for extract the message from 322 * firmware. It will contain dedicated info in 323 * ws-07-0063-v06-rtl819x-command-packet-specification-070315.doc. 324 * Please refer to chapter "Interrupt Status Element". 325 * 326 * Input: struct net_device *dev, 327 * u8* pmsg - Message Pointer of the command packet. 328 * 329 * Output: NONE 330 * 331 * Return: NONE 332 * 333 * Revised History: 334 * When Who Remark 335 * 05/12/2008 amy Add this for rtl8192 porting from windows code. 336 * 337 *---------------------------------------------------------------------------*/ 338static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg) 339{ 340 cmpk_intr_sta_t rx_intr_status; /* */ 341 struct r8192_priv *priv = ieee80211_priv(dev); 342 343 DMESG("---> cmpk_Handle_Interrupt_Status()\n"); 344 345 /* 1. Extract TX feedback info from RFD to temp structure buffer. */ 346 /* It seems that FW use big endian(MIPS) and DRV use little endian in 347 windows OS. So we have to read the content byte by byte or transfer 348 endian type before copy the message copy. */ 349 rx_intr_status.length = pmsg[1]; 350 if (rx_intr_status.length != (sizeof(cmpk_intr_sta_t) - 2)) { 351 DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n"); 352 return; 353 } 354 355 356 // Statistics of beacon for ad-hoc mode. 357 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) { 358 //2 maybe need endian transform? 359 rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4)); 360 361 DMESG("interrupt status = 0x%x\n", rx_intr_status.interrupt_status); 362 363 if (rx_intr_status.interrupt_status & ISR_TxBcnOk) { 364 priv->ieee80211->bibsscoordinator = true; 365 priv->stats.txbeaconokint++; 366 } else if (rx_intr_status.interrupt_status & ISR_TxBcnErr) { 367 priv->ieee80211->bibsscoordinator = false; 368 priv->stats.txbeaconerr++; 369 } 370 371 if (rx_intr_status.interrupt_status & ISR_BcnTimerIntr) 372 cmdpkt_beacontimerinterrupt_819xusb(dev); 373 374 } 375 376 // Other informations in interrupt status we need? 377 378 379 DMESG("<---- cmpk_handle_interrupt_status()\n"); 380 381} /* cmpk_handle_interrupt_status */ 382 383 384/*----------------------------------------------------------------------------- 385 * Function: cmpk_handle_query_config_rx() 386 * 387 * Overview: The function is responsible for extract the message from 388 * firmware. It will contain dedicated info in 389 * ws-06-0063-rtl8190-command-packet-specification. Please 390 * refer to chapter "Beacon State Element". 391 * 392 * Input: u8 * pmsg - Message Pointer of the command packet. 393 * 394 * Output: NONE 395 * 396 * Return: NONE 397 * 398 * Revised History: 399 * When Who Remark 400 * 05/12/2008 amy Create Version 0 porting from windows code. 401 * 402 *---------------------------------------------------------------------------*/ 403static void cmpk_handle_query_config_rx(struct net_device *dev, u8 *pmsg) 404{ 405 cmpk_query_cfg_t rx_query_cfg; /* */ 406 407 408 /* 1. Extract TX feedback info from RFD to temp structure buffer. */ 409 /* It seems that FW use big endian(MIPS) and DRV use little endian in 410 windows OS. So we have to read the content byte by byte or transfer 411 endian type before copy the message copy. */ 412 rx_query_cfg.cfg_action = (pmsg[4] & 0x80000000) >> 31; 413 rx_query_cfg.cfg_type = (pmsg[4] & 0x60) >> 5; 414 rx_query_cfg.cfg_size = (pmsg[4] & 0x18) >> 3; 415 rx_query_cfg.cfg_page = (pmsg[6] & 0x0F) >> 0; 416 rx_query_cfg.cfg_offset = pmsg[7]; 417 rx_query_cfg.value = (pmsg[8] << 24) | (pmsg[9] << 16) | 418 (pmsg[10] << 8) | (pmsg[11] << 0); 419 rx_query_cfg.mask = (pmsg[12] << 24) | (pmsg[13] << 16) | 420 (pmsg[14] << 8) | (pmsg[15] << 0); 421 422} /* cmpk_Handle_Query_Config_Rx */ 423 424 425/*----------------------------------------------------------------------------- 426 * Function: cmpk_count_tx_status() 427 * 428 * Overview: Count aggregated tx status from firmwar of one type rx command 429 * packet element id = RX_TX_STATUS. 430 * 431 * Input: NONE 432 * 433 * Output: NONE 434 * 435 * Return: NONE 436 * 437 * Revised History: 438 * When Who Remark 439 * 05/12/2008 amy Create Version 0 porting from windows code. 440 * 441 *---------------------------------------------------------------------------*/ 442static void cmpk_count_tx_status(struct net_device *dev, 443 cmpk_tx_status_t *pstx_status) 444{ 445 struct r8192_priv *priv = ieee80211_priv(dev); 446 447#ifdef ENABLE_PS 448 449 RT_RF_POWER_STATE rtstate; 450 451 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); 452 453 // When RF is off, we should not count the packet for hw/sw synchronize 454 // reason, ie. there may be a duration while sw switch is changed and hw 455 // switch is being changed. 2006.12.04, by shien chang. 456 if (rtState == eRfOff) 457 return; 458#endif 459 460 priv->stats.txfeedbackok += pstx_status->txok; 461 priv->stats.txoktotal += pstx_status->txok; 462 463 priv->stats.txfeedbackfail += pstx_status->txfail; 464 priv->stats.txerrtotal += pstx_status->txfail; 465 466 priv->stats.txretrycount += pstx_status->txretry; 467 priv->stats.txfeedbackretry += pstx_status->txretry; 468 469 470 priv->stats.txmulticast += pstx_status->txmcok; 471 priv->stats.txbroadcast += pstx_status->txbcok; 472 priv->stats.txunicast += pstx_status->txucok; 473 474 priv->stats.txerrmulticast += pstx_status->txmcfail; 475 priv->stats.txerrbroadcast += pstx_status->txbcfail; 476 priv->stats.txerrunicast += pstx_status->txucfail; 477 478 priv->stats.txbytesmulticast += pstx_status->txmclength; 479 priv->stats.txbytesbroadcast += pstx_status->txbclength; 480 priv->stats.txbytesunicast += pstx_status->txuclength; 481 482 priv->stats.last_packet_rate = pstx_status->rate; 483} /* cmpk_CountTxStatus */ 484 485 486 487/*----------------------------------------------------------------------------- 488 * Function: cmpk_handle_tx_status() 489 * 490 * Overview: Firmware add a new tx feedback status to reduce rx command 491 * packet buffer operation load. 492 * 493 * Input: NONE 494 * 495 * Output: NONE 496 * 497 * Return: NONE 498 * 499 * Revised History: 500 * When Who Remark 501 * 05/12/2008 amy Create Version 0 porting from windows code. 502 * 503 *---------------------------------------------------------------------------*/ 504static void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg) 505{ 506 cmpk_tx_status_t rx_tx_sts; /* */ 507 508 memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(cmpk_tx_status_t)); 509 /* 2. Use tx feedback info to count TX statistics. */ 510 cmpk_count_tx_status(dev, &rx_tx_sts); 511 512} /* cmpk_Handle_Tx_Status */ 513 514 515/*----------------------------------------------------------------------------- 516 * Function: cmpk_handle_tx_rate_history() 517 * 518 * Overview: Firmware add a new tx rate history 519 * 520 * Input: NONE 521 * 522 * Output: NONE 523 * 524 * Return: NONE 525 * 526 * Revised History: 527 * When Who Remark 528 * 05/12/2008 amy Create Version 0 porting from windows code. 529 * 530 *---------------------------------------------------------------------------*/ 531static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg) 532{ 533 cmpk_tx_rahis_t *ptxrate; 534 u8 i, j; 535 u16 length = sizeof(cmpk_tx_rahis_t); 536 u32 *ptemp; 537 struct r8192_priv *priv = ieee80211_priv(dev); 538 539 540#ifdef ENABLE_PS 541 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE, (pu1Byte)(&rtState)); 542 543 // When RF is off, we should not count the packet for hw/sw synchronize 544 // reason, ie. there may be a duration while sw switch is changed and hw 545 // switch is being changed. 2006.12.04, by shien chang. 546 if (rtState == eRfOff) 547 return; 548#endif 549 550 ptemp = (u32 *)pmsg; 551 552 // 553 // Do endian transfer to word alignment(16 bits) for windows system. 554 // You must do different endian transfer for linux and MAC OS 555 // 556 for (i = 0; i < (length/4); i++) { 557 u16 temp1, temp2; 558 559 temp1 = ptemp[i] & 0x0000FFFF; 560 temp2 = ptemp[i] >> 16; 561 ptemp[i] = (temp1 << 16) | temp2; 562 } 563 564 ptxrate = (cmpk_tx_rahis_t *)pmsg; 565 566 if (ptxrate == NULL) 567 return; 568 569 for (i = 0; i < 16; i++) { 570 // Collect CCK rate packet num 571 if (i < 4) 572 priv->stats.txrate.cck[i] += ptxrate->cck[i]; 573 574 // Collect OFDM rate packet num 575 if (i < 8) 576 priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i]; 577 578 for (j = 0; j < 4; j++) 579 priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i]; 580 } 581 582} /* cmpk_Handle_Tx_Rate_History */ 583 584 585/*----------------------------------------------------------------------------- 586 * Function: cmpk_message_handle_rx() 587 * 588 * Overview: In the function, we will capture different RX command packet 589 * info. Every RX command packet element has different message 590 * length and meaning in content. We only support three type of RX 591 * command packet now. Please refer to document 592 * ws-06-0063-rtl8190-command-packet-specification. 593 * 594 * Input: NONE 595 * 596 * Output: NONE 597 * 598 * Return: NONE 599 * 600 * Revised History: 601 * When Who Remark 602 * 05/06/2008 amy Create Version 0 porting from windows code. 603 * 604 *---------------------------------------------------------------------------*/ 605extern u32 cmpk_message_handle_rx(struct net_device *dev, 606 struct ieee80211_rx_stats *pstats) 607{ 608 int total_length; 609 u8 cmd_length, exe_cnt = 0; 610 u8 element_id; 611 u8 *pcmd_buff; 612 613 /* 0. Check inpt arguments. If is is a command queue message or pointer is 614 null. */ 615 if (pstats == NULL) 616 return 0; /* This is not a command packet. */ 617 618 /* 1. Read received command packet message length from RFD. */ 619 total_length = pstats->Length; 620 621 /* 2. Read virtual address from RFD. */ 622 pcmd_buff = pstats->virtual_address; 623 624 /* 3. Read command packet element id and length. */ 625 element_id = pcmd_buff[0]; 626 627 /* 4. Check every received command packet content according to different 628 element type. Because FW may aggregate RX command packet to minimize 629 transmit time between DRV and FW.*/ 630 // Add a counter to prevent the lock in the loop from being held too long 631 while (total_length > 0 && exe_cnt++ < 100) { 632 /* 2007/01/17 MH We support aggregation of different cmd in the same packet. */ 633 element_id = pcmd_buff[0]; 634 635 switch (element_id) { 636 case RX_TX_FEEDBACK: 637 cmpk_handle_tx_feedback(dev, pcmd_buff); 638 cmd_length = CMPK_RX_TX_FB_SIZE; 639 break; 640 641 case RX_INTERRUPT_STATUS: 642 cmpk_handle_interrupt_status(dev, pcmd_buff); 643 cmd_length = sizeof(cmpk_intr_sta_t); 644 break; 645 646 case BOTH_QUERY_CONFIG: 647 cmpk_handle_query_config_rx(dev, pcmd_buff); 648 cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE; 649 break; 650 651 case RX_TX_STATUS: 652 cmpk_handle_tx_status(dev, pcmd_buff); 653 cmd_length = CMPK_RX_TX_STS_SIZE; 654 break; 655 656 case RX_TX_PER_PKT_FEEDBACK: 657 // You must at lease add a switch case element here, 658 // Otherwise, we will jump to default case. 659 cmd_length = CMPK_RX_TX_FB_SIZE; 660 break; 661 662 case RX_TX_RATE_HISTORY: 663 cmpk_handle_tx_rate_history(dev, pcmd_buff); 664 cmd_length = CMPK_TX_RAHIS_SIZE; 665 break; 666 667 default: 668 669 RT_TRACE(COMP_ERR, "---->cmpk_message_handle_rx():unknow CMD Element\n"); 670 return 1; /* This is a command packet. */ 671 } 672 673 total_length -= cmd_length; 674 pcmd_buff += cmd_length; 675 } 676 return 1; /* This is a command packet. */ 677 678} /* CMPK_Message_Handle_Rx */ 679