0001
0002
0003
0004
0005
0006
0007
0008
0009
0010
0011
0012
0013
0014
0015
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025
0026
0027 #include "r8192U.h"
0028 #include "r819xU_cmdpkt.h"
0029
0030 rt_status SendTxCommandPacket(struct net_device *dev, void *pData, u32 DataLen)
0031 {
0032 struct r8192_priv *priv = ieee80211_priv(dev);
0033 struct sk_buff *skb;
0034 struct cb_desc *tcb_desc;
0035
0036
0037
0038
0039 skb = dev_alloc_skb(USB_HWDESC_HEADER_LEN + DataLen + 4);
0040 if (!skb)
0041 return RT_STATUS_FAILURE;
0042 memcpy((unsigned char *)(skb->cb), &dev, sizeof(dev));
0043 tcb_desc = (struct cb_desc *)(skb->cb + MAX_DEV_ADDR_SIZE);
0044 tcb_desc->queue_index = TXCMD_QUEUE;
0045 tcb_desc->bCmdOrInit = DESC_PACKET_TYPE_NORMAL;
0046 tcb_desc->bLastIniPkt = 0;
0047 skb_reserve(skb, USB_HWDESC_HEADER_LEN);
0048 skb_put_data(skb, pData, DataLen);
0049 tcb_desc->txbuf_size = (u16)DataLen;
0050
0051 if (!priv->ieee80211->check_nic_enough_desc(dev, tcb_desc->queue_index) ||
0052 (!skb_queue_empty(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index])) ||
0053 (priv->ieee80211->queue_stop)) {
0054 RT_TRACE(COMP_FIRMWARE, "=== NULL packet ======> tx full!\n");
0055 skb_queue_tail(&priv->ieee80211->skb_waitQ[tcb_desc->queue_index], skb);
0056 } else {
0057 priv->ieee80211->softmac_hard_start_xmit(skb, dev);
0058 }
0059
0060 return RT_STATUS_SUCCESS;
0061 }
0062
0063 static void cmpk_count_txstatistic(struct net_device *dev, struct cmd_pkt_tx_feedback *pstx_fb)
0064 {
0065 struct r8192_priv *priv = ieee80211_priv(dev);
0066 #ifdef ENABLE_PS
0067 RT_RF_POWER_STATE rtState;
0068
0069 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE,
0070 (pu1Byte)(&rtState));
0071
0072
0073
0074
0075
0076 if (rtState == eRfOff)
0077 return;
0078 #endif
0079
0080 #ifdef TODO
0081 if (pAdapter->bInHctTest)
0082 return;
0083 #endif
0084
0085
0086
0087
0088 if (pstx_fb->tok) {
0089 priv->stats.txfeedbackok++;
0090 priv->stats.txoktotal++;
0091 priv->stats.txokbytestotal += pstx_fb->pkt_length;
0092 priv->stats.txokinperiod++;
0093
0094
0095 if (pstx_fb->pkt_type == PACKET_MULTICAST) {
0096 priv->stats.txmulticast++;
0097 priv->stats.txbytesmulticast += pstx_fb->pkt_length;
0098 } else if (pstx_fb->pkt_type == PACKET_BROADCAST) {
0099 priv->stats.txbroadcast++;
0100 priv->stats.txbytesbroadcast += pstx_fb->pkt_length;
0101 } else {
0102 priv->stats.txunicast++;
0103 priv->stats.txbytesunicast += pstx_fb->pkt_length;
0104 }
0105 } else {
0106 priv->stats.txfeedbackfail++;
0107 priv->stats.txerrtotal++;
0108 priv->stats.txerrbytestotal += pstx_fb->pkt_length;
0109
0110
0111 if (pstx_fb->pkt_type == PACKET_MULTICAST)
0112 priv->stats.txerrmulticast++;
0113 else if (pstx_fb->pkt_type == PACKET_BROADCAST)
0114 priv->stats.txerrbroadcast++;
0115 else
0116 priv->stats.txerrunicast++;
0117 }
0118
0119 priv->stats.txretrycount += pstx_fb->retry_cnt;
0120 priv->stats.txfeedbackretry += pstx_fb->retry_cnt;
0121 }
0122
0123
0124
0125
0126
0127
0128
0129
0130
0131
0132
0133
0134
0135
0136
0137
0138
0139
0140
0141
0142
0143
0144
0145 static void cmpk_handle_tx_feedback(struct net_device *dev, u8 *pmsg)
0146 {
0147 struct r8192_priv *priv = ieee80211_priv(dev);
0148 struct cmd_pkt_tx_feedback rx_tx_fb;
0149
0150 priv->stats.txfeedback++;
0151
0152
0153
0154
0155
0156
0157
0158 memcpy((u8 *)&rx_tx_fb, pmsg, sizeof(struct cmd_pkt_tx_feedback));
0159
0160 cmpk_count_txstatistic(dev, &rx_tx_fb);
0161
0162
0163
0164
0165
0166 }
0167
0168 static void cmdpkt_beacontimerinterrupt_819xusb(struct net_device *dev)
0169 {
0170 struct r8192_priv *priv = ieee80211_priv(dev);
0171 u16 tx_rate;
0172
0173
0174 if (priv->ieee80211->current_network.mode == IEEE_A ||
0175 priv->ieee80211->current_network.mode == IEEE_N_5G ||
0176 (priv->ieee80211->current_network.mode == IEEE_N_24G &&
0177 (!priv->ieee80211->pHTInfo->bCurSuppCCK))) {
0178 tx_rate = 60;
0179 DMESG("send beacon frame tx rate is 6Mbpm\n");
0180 } else {
0181 tx_rate = 10;
0182 DMESG("send beacon frame tx rate is 1Mbpm\n");
0183 }
0184
0185 rtl819xusb_beacon_tx(dev, tx_rate);
0186 }
0187
0188
0189
0190
0191
0192
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208
0209 static void cmpk_handle_interrupt_status(struct net_device *dev, u8 *pmsg)
0210 {
0211 struct cmd_pkt_interrupt_status rx_intr_status;
0212 struct r8192_priv *priv = ieee80211_priv(dev);
0213
0214 DMESG("---> cmpk_Handle_Interrupt_Status()\n");
0215
0216
0217
0218
0219
0220
0221 rx_intr_status.length = pmsg[1];
0222 if (rx_intr_status.length != (sizeof(struct cmd_pkt_interrupt_status) - 2)) {
0223 DMESG("cmpk_Handle_Interrupt_Status: wrong length!\n");
0224 return;
0225 }
0226
0227
0228 if (priv->ieee80211->iw_mode == IW_MODE_ADHOC) {
0229
0230 rx_intr_status.interrupt_status = *((u32 *)(pmsg + 4));
0231
0232 DMESG("interrupt status = 0x%x\n",
0233 rx_intr_status.interrupt_status);
0234
0235 if (rx_intr_status.interrupt_status & ISR_TX_BCN_OK) {
0236 priv->ieee80211->bibsscoordinator = true;
0237 priv->stats.txbeaconokint++;
0238 } else if (rx_intr_status.interrupt_status & ISR_TX_BCN_ERR) {
0239 priv->ieee80211->bibsscoordinator = false;
0240 priv->stats.txbeaconerr++;
0241 }
0242
0243 if (rx_intr_status.interrupt_status & ISR_BCN_TIMER_INTR)
0244 cmdpkt_beacontimerinterrupt_819xusb(dev);
0245 }
0246
0247
0248
0249 DMESG("<---- cmpk_handle_interrupt_status()\n");
0250 }
0251
0252
0253
0254
0255
0256
0257
0258
0259
0260
0261
0262
0263
0264
0265
0266
0267
0268
0269
0270 static void cmpk_count_tx_status(struct net_device *dev,
0271 cmpk_tx_status_t *pstx_status)
0272 {
0273 struct r8192_priv *priv = ieee80211_priv(dev);
0274
0275 #ifdef ENABLE_PS
0276
0277 RT_RF_POWER_STATE rtstate;
0278
0279 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE,
0280 (pu1Byte)(&rtState));
0281
0282
0283
0284
0285
0286 if (rtState == eRfOff)
0287 return;
0288 #endif
0289
0290 priv->stats.txfeedbackok += pstx_status->txok;
0291 priv->stats.txoktotal += pstx_status->txok;
0292
0293 priv->stats.txfeedbackfail += pstx_status->txfail;
0294 priv->stats.txerrtotal += pstx_status->txfail;
0295
0296 priv->stats.txretrycount += pstx_status->txretry;
0297 priv->stats.txfeedbackretry += pstx_status->txretry;
0298
0299 priv->stats.txmulticast += pstx_status->txmcok;
0300 priv->stats.txbroadcast += pstx_status->txbcok;
0301 priv->stats.txunicast += pstx_status->txucok;
0302
0303 priv->stats.txerrmulticast += pstx_status->txmcfail;
0304 priv->stats.txerrbroadcast += pstx_status->txbcfail;
0305 priv->stats.txerrunicast += pstx_status->txucfail;
0306
0307 priv->stats.txbytesmulticast += pstx_status->txmclength;
0308 priv->stats.txbytesbroadcast += pstx_status->txbclength;
0309 priv->stats.txbytesunicast += pstx_status->txuclength;
0310
0311 priv->stats.last_packet_rate = pstx_status->rate;
0312 }
0313
0314
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328
0329
0330
0331
0332 static void cmpk_handle_tx_status(struct net_device *dev, u8 *pmsg)
0333 {
0334 cmpk_tx_status_t rx_tx_sts;
0335
0336 memcpy((void *)&rx_tx_sts, (void *)pmsg, sizeof(cmpk_tx_status_t));
0337
0338 cmpk_count_tx_status(dev, &rx_tx_sts);
0339 }
0340
0341
0342
0343
0344
0345
0346
0347
0348
0349
0350
0351
0352
0353
0354
0355
0356
0357
0358 static void cmpk_handle_tx_rate_history(struct net_device *dev, u8 *pmsg)
0359 {
0360 cmpk_tx_rahis_t *ptxrate;
0361 u8 i, j;
0362 u16 length = sizeof(cmpk_tx_rahis_t);
0363 u32 *ptemp;
0364 struct r8192_priv *priv = ieee80211_priv(dev);
0365
0366 #ifdef ENABLE_PS
0367 pAdapter->HalFunc.GetHwRegHandler(pAdapter, HW_VAR_RF_STATE,
0368 (pu1Byte)(&rtState));
0369
0370
0371
0372
0373
0374 if (rtState == eRfOff)
0375 return;
0376 #endif
0377
0378 ptemp = (u32 *)pmsg;
0379
0380
0381
0382
0383 for (i = 0; i < (length/4); i++) {
0384 u16 temp1, temp2;
0385
0386 temp1 = ptemp[i] & 0x0000FFFF;
0387 temp2 = ptemp[i] >> 16;
0388 ptemp[i] = (temp1 << 16) | temp2;
0389 }
0390
0391 ptxrate = (cmpk_tx_rahis_t *)pmsg;
0392
0393 if (!ptxrate)
0394 return;
0395
0396 for (i = 0; i < 16; i++) {
0397
0398 if (i < 4)
0399 priv->stats.txrate.cck[i] += ptxrate->cck[i];
0400
0401
0402 if (i < 8)
0403 priv->stats.txrate.ofdm[i] += ptxrate->ofdm[i];
0404
0405 for (j = 0; j < 4; j++)
0406 priv->stats.txrate.ht_mcs[j][i] += ptxrate->ht_mcs[j][i];
0407 }
0408 }
0409
0410
0411
0412
0413
0414
0415
0416
0417
0418
0419
0420
0421
0422
0423
0424
0425
0426
0427
0428
0429
0430
0431 u32 cmpk_message_handle_rx(struct net_device *dev,
0432 struct ieee80211_rx_stats *pstats)
0433 {
0434 int total_length;
0435 u8 cmd_length, exe_cnt = 0;
0436 u8 element_id;
0437 u8 *pcmd_buff;
0438
0439
0440
0441
0442 if (!pstats)
0443 return 0;
0444
0445
0446 total_length = pstats->Length;
0447
0448
0449 pcmd_buff = pstats->virtual_address;
0450
0451
0452 element_id = pcmd_buff[0];
0453
0454
0455
0456
0457
0458
0459
0460
0461 while (total_length > 0 && exe_cnt++ < 100) {
0462
0463 element_id = pcmd_buff[0];
0464
0465 switch (element_id) {
0466 case RX_TX_FEEDBACK:
0467 cmpk_handle_tx_feedback(dev, pcmd_buff);
0468 cmd_length = CMPK_RX_TX_FB_SIZE;
0469 break;
0470
0471 case RX_INTERRUPT_STATUS:
0472 cmpk_handle_interrupt_status(dev, pcmd_buff);
0473 cmd_length = sizeof(struct cmd_pkt_interrupt_status);
0474 break;
0475
0476 case BOTH_QUERY_CONFIG:
0477 cmd_length = CMPK_BOTH_QUERY_CONFIG_SIZE;
0478 break;
0479
0480 case RX_TX_STATUS:
0481 cmpk_handle_tx_status(dev, pcmd_buff);
0482 cmd_length = CMPK_RX_TX_STS_SIZE;
0483 break;
0484
0485 case RX_TX_PER_PKT_FEEDBACK:
0486
0487
0488
0489 cmd_length = CMPK_RX_TX_FB_SIZE;
0490 break;
0491
0492 case RX_TX_RATE_HISTORY:
0493 cmpk_handle_tx_rate_history(dev, pcmd_buff);
0494 cmd_length = CMPK_TX_RAHIS_SIZE;
0495 break;
0496
0497 default:
0498
0499 RT_TRACE(COMP_ERR, "---->%s():unknown CMD Element\n",
0500 __func__);
0501 return 1;
0502 }
0503
0504 total_length -= cmd_length;
0505 pcmd_buff += cmd_length;
0506 }
0507 return 1;
0508 }