static void s_vFillCTSHead( struct vnt_private *pDevice, unsigned int uDMAIdx, unsigned char byPktType, void *pvCTS, unsigned int cbFrameLength, bool bNeedAck, bool bDisCRC, unsigned short wCurrentRate, unsigned char byFBOption ) { unsigned int uCTSFrameLen = 14; if (!pvCTS) return; if (bDisCRC) { /* When CRCDIS bit is on, H/W forgot to generate FCS for * CTS frame, in this case we need to decrease its length by 4. */ uCTSFrameLen -= 4; } if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) { /* Auto Fall back */ struct vnt_cts_fb *buf = pvCTS; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->b); buf->duration_ba = s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); /* Get CTSDuration_ba_f0 */ buf->cts_duration_ba_f0 = s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); /* Get CTSDuration_ba_f1 */ buf->cts_duration_ba_f1 = s_uGetRTSCTSDuration(pDevice, CTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); /* Get CTS Frame body */ buf->data.duration = buf->duration_ba; buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); buf->reserved2 = 0x0; ether_addr_copy(buf->data.ra, pDevice->abyCurrentNetAddr); } else { /* if (byFBOption != AUTO_FB_NONE && uDMAIdx != TYPE_ATIMDMA && uDMAIdx != TYPE_BEACONDMA) */ struct vnt_cts *buf = pvCTS; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, uCTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->b); /* Get CTSDuration_ba */ buf->duration_ba = s_uGetRTSCTSDuration(pDevice, CTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); /* Get CTS Frame body */ buf->data.duration = buf->duration_ba; buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_CTS); buf->reserved2 = 0x0; ether_addr_copy(buf->data.ra, pDevice->abyCurrentNetAddr); } } }
static void s_vFillRTSHead( struct vnt_private *pDevice, unsigned char byPktType, void *pvRTS, unsigned int cbFrameLength, bool bNeedAck, bool bDisCRC, struct ieee80211_hdr *hdr, unsigned short wCurrentRate, unsigned char byFBOption ) { unsigned int uRTSFrameLen = 20; if (!pvRTS) return; if (bDisCRC) { /* When CRCDIS bit is on, H/W forgot to generate FCS for * RTS frame, in this case we need to decrease its length by 4. */ uRTSFrameLen -= 4; } /* Note: So far RTSHead doesn't appear in ATIM & Beacom DMA, * so we don't need to take them into account. * Otherwise, we need to modify codes for them. */ if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { if (byFBOption == AUTO_FB_NONE) { struct vnt_rts_g *buf = pvRTS; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->b); vnt_get_phy_field(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, &buf->a); /* Get Duration */ buf->duration_bb = s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption); buf->duration_aa = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->duration_ba = s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->data.duration = buf->duration_aa; /* Get RTS Frame body */ buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); ether_addr_copy(buf->data.ra, hdr->addr1); ether_addr_copy(buf->data.ta, hdr->addr2); } else { struct vnt_rts_g_fb *buf = pvRTS; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->b); vnt_get_phy_field(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, &buf->a); /* Get Duration */ buf->duration_bb = s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, byFBOption); buf->duration_aa = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->duration_ba = s_uGetRTSCTSDuration(pDevice, RTSDUR_BA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->rts_duration_ba_f0 = s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->rts_duration_aa_f0 = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->rts_duration_ba_f1 = s_uGetRTSCTSDuration(pDevice, RTSDUR_BA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->rts_duration_aa_f1 = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->data.duration = buf->duration_aa; /* Get RTS Frame body */ buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); ether_addr_copy(buf->data.ra, hdr->addr1); ether_addr_copy(buf->data.ta, hdr->addr2); } /* if (byFBOption == AUTO_FB_NONE) */ } else if (byPktType == PK_TYPE_11A) { if (byFBOption == AUTO_FB_NONE) { struct vnt_rts_ab *buf = pvRTS; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, &buf->ab); /* Get Duration */ buf->duration = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->data.duration = buf->duration; /* Get RTS Frame body */ buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); ether_addr_copy(buf->data.ra, hdr->addr1); ether_addr_copy(buf->data.ta, hdr->addr2); } else { struct vnt_rts_a_fb *buf = pvRTS; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, uRTSFrameLen, pDevice->byTopOFDMBasicRate, byPktType, &buf->a); /* Get Duration */ buf->duration = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->rts_duration_f0 = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->rts_duration_f1 = s_uGetRTSCTSDuration(pDevice, RTSDUR_AA_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->data.duration = buf->duration; /* Get RTS Frame body */ buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); ether_addr_copy(buf->data.ra, hdr->addr1); ether_addr_copy(buf->data.ta, hdr->addr2); } } else if (byPktType == PK_TYPE_11B) { struct vnt_rts_ab *buf = pvRTS; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, uRTSFrameLen, pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->ab); /* Get Duration */ buf->duration = s_uGetRTSCTSDuration(pDevice, RTSDUR_BB, cbFrameLength, byPktType, wCurrentRate, bNeedAck, byFBOption); buf->data.duration = buf->duration; /* Get RTS Frame body */ buf->data.frame_control = cpu_to_le16(IEEE80211_FTYPE_CTL | IEEE80211_STYPE_RTS); ether_addr_copy(buf->data.ra, hdr->addr1); ether_addr_copy(buf->data.ta, hdr->addr2); } }
static int vnt_beacon_xmit(struct vnt_private *priv, struct sk_buff *skb) { struct vnt_tx_short_buf_head *short_head = (struct vnt_tx_short_buf_head *)priv->tx_beacon_bufs; struct ieee80211_mgmt *mgmt_hdr = (struct ieee80211_mgmt *) (priv->tx_beacon_bufs + sizeof(*short_head)); struct ieee80211_tx_info *info; u32 frame_size = skb->len + 4; u16 current_rate; memset(priv->tx_beacon_bufs, 0, sizeof(*short_head)); if (priv->byBBType == BB_TYPE_11A) { current_rate = RATE_6M; /* Get SignalField,ServiceField,Length */ vnt_get_phy_field(priv, frame_size, current_rate, PK_TYPE_11A, &short_head->ab); /* Get Duration and TimeStampOff */ short_head->duration = cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, frame_size, PK_TYPE_11A, current_rate, false, 0, 0, 1, AUTO_FB_NONE)); short_head->time_stamp_off = vnt_time_stamp_off(priv, current_rate); } else { current_rate = RATE_1M; short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_11B); /* Get SignalField,ServiceField,Length */ vnt_get_phy_field(priv, frame_size, current_rate, PK_TYPE_11B, &short_head->ab); /* Get Duration and TimeStampOff */ short_head->duration = cpu_to_le16((u16)s_uGetDataDuration(priv, DATADUR_B, frame_size, PK_TYPE_11B, current_rate, false, 0, 0, 1, AUTO_FB_NONE)); short_head->time_stamp_off = vnt_time_stamp_off(priv, current_rate); } short_head->fifo_ctl |= cpu_to_le16(FIFOCTL_GENINT); /* Copy Beacon */ memcpy(mgmt_hdr, skb->data, skb->len); /* time stamp always 0 */ mgmt_hdr->u.beacon.timestamp = 0; info = IEEE80211_SKB_CB(skb); if (info->flags & IEEE80211_TX_CTL_ASSIGN_SEQ) { struct ieee80211_hdr *hdr = (struct ieee80211_hdr *)mgmt_hdr; hdr->duration_id = 0; hdr->seq_ctrl = cpu_to_le16(priv->wSeqCounter << 4); } priv->wSeqCounter++; if (priv->wSeqCounter > 0x0fff) priv->wSeqCounter = 0; priv->wBCNBufLen = sizeof(*short_head) + skb->len; MACvSetCurrBCNTxDescAddr(priv->PortOffset, priv->tx_beacon_dma); MACvSetCurrBCNLength(priv->PortOffset, priv->wBCNBufLen); /* Set auto Transmit on */ MACvRegBitsOn(priv->PortOffset, MAC_REG_TCR, TCR_AUTOBCNTX); /* Poll Transmit the adapter */ MACvTransmitBCN(priv->PortOffset); return 0; }
static __le16 s_uFillDataHead( struct vnt_private *pDevice, unsigned char byPktType, void *pTxDataHead, unsigned int cbFrameLength, unsigned int uDMAIdx, bool bNeedAck, unsigned int uFragIdx, unsigned int cbLastFragmentSize, unsigned int uMACfragNum, unsigned char byFBOption, unsigned short wCurrentRate, bool is_pspoll ) { if (!pTxDataHead) return 0; if (byPktType == PK_TYPE_11GB || byPktType == PK_TYPE_11GA) { if (byFBOption == AUTO_FB_NONE) { struct vnt_tx_datahead_g *buf = pTxDataHead; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->a); vnt_get_phy_field(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->b); if (is_pspoll) { __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); buf->duration_a = dur; buf->duration_b = dur; } else { /* Get Duration and TimeStamp */ buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); } buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate); buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate); return buf->duration_a; } else { /* Auto Fallback */ struct vnt_tx_datahead_g_fb *buf = pTxDataHead; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->a); vnt_get_phy_field(pDevice, cbFrameLength, pDevice->byTopCCKBasicRate, PK_TYPE_11B, &buf->b); /* Get Duration and TimeStamp */ buf->duration_a = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); buf->duration_b = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, PK_TYPE_11B, pDevice->byTopCCKBasicRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); buf->duration_a_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); buf->duration_a_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); buf->time_stamp_off_a = vnt_time_stamp_off(pDevice, wCurrentRate); buf->time_stamp_off_b = vnt_time_stamp_off(pDevice, pDevice->byTopCCKBasicRate); return buf->duration_a; } /* if (byFBOption == AUTO_FB_NONE) */ } else if (byPktType == PK_TYPE_11A) { if (byFBOption != AUTO_FB_NONE) { /* Auto Fallback */ struct vnt_tx_datahead_a_fb *buf = pTxDataHead; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->a); /* Get Duration and TimeStampOff */ buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); buf->duration_f0 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F0, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); buf->duration_f1 = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A_F1, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); return buf->duration; } else { struct vnt_tx_datahead_ab *buf = pTxDataHead; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->ab); if (is_pspoll) { __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); buf->duration = dur; } else { /* Get Duration and TimeStampOff */ buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_A, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); } buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); return buf->duration; } } else { struct vnt_tx_datahead_ab *buf = pTxDataHead; /* Get SignalField, ServiceField & Length */ vnt_get_phy_field(pDevice, cbFrameLength, wCurrentRate, byPktType, &buf->ab); if (is_pspoll) { __le16 dur = cpu_to_le16(pDevice->current_aid | BIT(14) | BIT(15)); buf->duration = dur; } else { /* Get Duration and TimeStampOff */ buf->duration = cpu_to_le16((u16)s_uGetDataDuration(pDevice, DATADUR_B, cbFrameLength, byPktType, wCurrentRate, bNeedAck, uFragIdx, cbLastFragmentSize, uMACfragNum, byFBOption)); } buf->time_stamp_off = vnt_time_stamp_off(pDevice, wCurrentRate); return buf->duration; } return 0; }
void vnt_set_rspinf(struct vnt_private *priv, u8 bb_type) { struct vnt_phy_field phy[4]; u8 tx_rate[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; /* For OFDM */ u8 rsv_time[9] = {0, 0, 0, 0, 0, 0, 0, 0, 0}; u8 data[34]; int i; /*RSPINF_b_1*/ vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_1M), PK_TYPE_11B, &phy[0]); /*RSPINF_b_2*/ vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_2M), PK_TYPE_11B, &phy[1]); /*RSPINF_b_5*/ vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_5M), PK_TYPE_11B, &phy[2]); /*RSPINF_b_11*/ vnt_get_phy_field(priv, 14, vnt_get_cck_rate(priv, RATE_11M), PK_TYPE_11B, &phy[3]); /*RSPINF_a_6*/ vnt_calculate_ofdm_rate(RATE_6M, bb_type, &tx_rate[0], &rsv_time[0]); /*RSPINF_a_9*/ vnt_calculate_ofdm_rate(RATE_9M, bb_type, &tx_rate[1], &rsv_time[1]); /*RSPINF_a_12*/ vnt_calculate_ofdm_rate(RATE_12M, bb_type, &tx_rate[2], &rsv_time[2]); /*RSPINF_a_18*/ vnt_calculate_ofdm_rate(RATE_18M, bb_type, &tx_rate[3], &rsv_time[3]); /*RSPINF_a_24*/ vnt_calculate_ofdm_rate(RATE_24M, bb_type, &tx_rate[4], &rsv_time[4]); /*RSPINF_a_36*/ vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_36M), bb_type, &tx_rate[5], &rsv_time[5]); /*RSPINF_a_48*/ vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_48M), bb_type, &tx_rate[6], &rsv_time[6]); /*RSPINF_a_54*/ vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M), bb_type, &tx_rate[7], &rsv_time[7]); /*RSPINF_a_72*/ vnt_calculate_ofdm_rate(vnt_get_ofdm_rate(priv, RATE_54M), bb_type, &tx_rate[8], &rsv_time[8]); put_unaligned(phy[0].len, (u16 *)&data[0]); data[2] = phy[0].signal; data[3] = phy[0].service; put_unaligned(phy[1].len, (u16 *)&data[4]); data[6] = phy[1].signal; data[7] = phy[1].service; put_unaligned(phy[2].len, (u16 *)&data[8]); data[10] = phy[2].signal; data[11] = phy[2].service; put_unaligned(phy[3].len, (u16 *)&data[12]); data[14] = phy[3].signal; data[15] = phy[3].service; for (i = 0; i < 9; i++) { data[16 + i * 2] = tx_rate[i]; data[16 + i * 2 + 1] = rsv_time[i]; } vnt_control_out(priv, MESSAGE_TYPE_WRITE, MAC_REG_RSPINF_B_1, MESSAGE_REQUEST_MACREG, 34, &data[0]); }