BOOL PSbSendNullPacket(void *hDeviceContext) { PSDevice pDevice = (PSDevice)hDeviceContext; PSTxMgmtPacket pTxPacket = NULL; PSMgmtObject pMgmt = &(pDevice->sMgmtObj); if (pDevice->bLinkPass == FALSE) { return FALSE; } if ((pDevice->bEnablePSMode == FALSE) && (pDevice->fTxDataInSleep == FALSE)){ return FALSE; } memset(pMgmt->pbyPSPacketPool, 0, sizeof(STxMgmtPacket) + WLAN_NULLDATA_FR_MAXLEN); pTxPacket = (PSTxMgmtPacket)pMgmt->pbyPSPacketPool; pTxPacket->p80211Header = (PUWLAN_80211HDR)((PBYTE)pTxPacket + sizeof(STxMgmtPacket)); if (pDevice->bEnablePSMode) { pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( ( WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | WLAN_SET_FC_PWRMGT(1) )); } else { pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16( ( WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL) | WLAN_SET_FC_PWRMGT(0) )); } if(pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) { pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1)); } memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; pTxPacket->cbPayloadLen = 0; // send the frame if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n"); return FALSE; } else { // DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet success....\n"); } return TRUE ; }
int PSbSendNullPacket(struct vnt_private *pDevice) { struct vnt_tx_mgmt *pTxPacket = NULL; struct vnt_manager *pMgmt = &pDevice->vnt_mgmt; u16 flags = 0; if (pDevice->bLinkPass == false) return false; if ((pDevice->bEnablePSMode == false) && (pDevice->fTxDataInSleep == false)) { return false; } memset(pMgmt->pbyPSPacketPool, 0, sizeof(struct vnt_tx_mgmt) + WLAN_NULLDATA_FR_MAXLEN); pTxPacket = (struct vnt_tx_mgmt *)pMgmt->pbyPSPacketPool; pTxPacket->p80211Header = (PUWLAN_80211HDR)((u8 *)pTxPacket + sizeof(struct vnt_tx_mgmt)); flags = WLAN_SET_FC_FTYPE(WLAN_TYPE_DATA) | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_NULL); if (pDevice->bEnablePSMode) flags |= WLAN_SET_FC_PWRMGT(1); else flags |= WLAN_SET_FC_PWRMGT(0); pTxPacket->p80211Header->sA3.wFrameCtl = cpu_to_le16(flags); if (pMgmt->eCurrMode != WMAC_MODE_IBSS_STA) pTxPacket->p80211Header->sA3.wFrameCtl |= cpu_to_le16((WORD)WLAN_SET_FC_TODS(1)); memcpy(pTxPacket->p80211Header->sA3.abyAddr1, pMgmt->abyCurrBSSID, WLAN_ADDR_LEN); memcpy(pTxPacket->p80211Header->sA3.abyAddr2, pMgmt->abyMACAddr, WLAN_ADDR_LEN); memcpy(pTxPacket->p80211Header->sA3.abyAddr3, pMgmt->abyCurrBSSID, WLAN_BSSID_LEN); pTxPacket->cbMPDULen = WLAN_HDR_ADDR3_LEN; pTxPacket->cbPayloadLen = 0; /* log error if sending failed */ if (csMgmt_xmit(pDevice, pTxPacket) != CMD_STATUS_PENDING) { DBG_PRT(MSG_LEVEL_DEBUG, KERN_INFO "Send Null Packet failed !\n"); return false; } return true; }
/*---------------------------------------------------------------- * p80211pb_ether_to_80211 * * Uses the contents of the ether frame and the etherconv setting * to build the elements of the 802.11 frame. * * We don't actually set * up the frame header here. That's the MAC's job. We're only handling * conversion of DIXII or 802.3+LLC frames to something that works * with 802.11. * * Note -- 802.11 header is NOT part of the skb. Likewise, the 802.11 * FCS is also not present and will need to be added elsewhere. * * Arguments: * ethconv Conversion type to perform * skb skbuff containing the ether frame * p80211_hdr 802.11 header * * Returns: * 0 on success, non-zero otherwise * * Call context: * May be called in interrupt or non-interrupt context ----------------------------------------------------------------*/ int skb_ether_to_p80211(wlandevice_t *wlandev, u32 ethconv, struct sk_buff *skb, union p80211_hdr *p80211_hdr, struct p80211_metawep *p80211_wep) { u16 fc; u16 proto; struct wlan_ethhdr e_hdr; struct wlan_llc *e_llc; struct wlan_snap *e_snap; int foo; memcpy(&e_hdr, skb->data, sizeof(e_hdr)); if (skb->len <= 0) { pr_debug("zero-length skb!\n"); return 1; } if (ethconv == WLAN_ETHCONV_ENCAP) { /* simplest case */ pr_debug("ENCAP len: %d\n", skb->len); /* here, we don't care what kind of ether frm. Just stick it */ /* in the 80211 payload */ /* which is to say, leave the skb alone. */ } else { /* step 1: classify ether frame, DIX or 802.3? */ proto = ntohs(e_hdr.type); if (proto <= 1500) { pr_debug("802.3 len: %d\n", skb->len); /* codes <= 1500 reserved for 802.3 lengths */ /* it's 802.3, pass ether payload unchanged, */ /* trim off ethernet header */ skb_pull(skb, WLAN_ETHHDR_LEN); /* leave off any PAD octets. */ skb_trim(skb, proto); } else { pr_debug("DIXII len: %d\n", skb->len); /* it's DIXII, time for some conversion */ /* trim off ethernet header */ skb_pull(skb, WLAN_ETHHDR_LEN); /* tack on SNAP */ e_snap = (struct wlan_snap *) skb_push(skb, sizeof(struct wlan_snap)); e_snap->type = htons(proto); if (ethconv == WLAN_ETHCONV_8021h && p80211_stt_findproto(proto)) { memcpy(e_snap->oui, oui_8021h, WLAN_IEEE_OUI_LEN); } else { memcpy(e_snap->oui, oui_rfc1042, WLAN_IEEE_OUI_LEN); } /* tack on llc */ e_llc = (struct wlan_llc *) skb_push(skb, sizeof(struct wlan_llc)); e_llc->dsap = 0xAA; /* SNAP, see IEEE 802 */ e_llc->ssap = 0xAA; e_llc->ctl = 0x03; } } /* Set up the 802.11 header */ /* It's a data frame */ fc = cpu_to_le16(WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY)); switch (wlandev->macmode) { case WLAN_MACMODE_IBSS_STA: memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN); memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN); memcpy(p80211_hdr->a3.a3, wlandev->bssid, ETH_ALEN); break; case WLAN_MACMODE_ESS_STA: fc |= cpu_to_le16(WLAN_SET_FC_TODS(1)); memcpy(p80211_hdr->a3.a1, wlandev->bssid, ETH_ALEN); memcpy(p80211_hdr->a3.a2, wlandev->netdev->dev_addr, ETH_ALEN); memcpy(p80211_hdr->a3.a3, &e_hdr.daddr, ETH_ALEN); break; case WLAN_MACMODE_ESS_AP: fc |= cpu_to_le16(WLAN_SET_FC_FROMDS(1)); memcpy(p80211_hdr->a3.a1, &e_hdr.daddr, ETH_ALEN); memcpy(p80211_hdr->a3.a2, wlandev->bssid, ETH_ALEN); memcpy(p80211_hdr->a3.a3, &e_hdr.saddr, ETH_ALEN); break; default: // printk(KERN_ERR ; return 1; break; } p80211_wep->data = NULL; if ((wlandev->hostwep & HOSTWEP_PRIVACYINVOKED) && (wlandev->hostwep & HOSTWEP_ENCRYPT)) { /* XXXX need to pick keynum other than default? */ p80211_wep->data = kmalloc(skb->len, GFP_ATOMIC); foo = wep_encrypt(wlandev, skb->data, p80211_wep->data, skb->len, (wlandev->hostwep & HOSTWEP_DEFAULTKEY_MASK), p80211_wep->iv, p80211_wep->icv); if (foo) { // printk(KERN_WARNING // "Host en-WEP failed, dropping frame (%d).\n", ; return 2; } fc |= cpu_to_le16(WLAN_SET_FC_ISWEP(1)); } /* skb->nh.raw = skb->data; */ p80211_hdr->a3.fc = fc; p80211_hdr->a3.dur = 0; p80211_hdr->a3.seq = 0; return 0; }
/************************************************************************** TRANSMIT - Transmit a frame ***************************************************************************/ static void prism2_transmit( struct nic *nic, const char *d, /* Destination */ unsigned int t, /* Type */ unsigned int s, /* size */ const char *p) /* Packet */ { hfa384x_t *hw = &hw_global; hfa384x_tx_frame_t txdesc; wlan_80211hdr_t p80211hdr = { wlan_llc_snap, {{0,0,0},0} }; uint16_t fid; uint16_t status; int result; // Request FID allocation result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_ALLOC), HFA384x_DRVR_TXBUF_MAX, 0, 0); if (result != 0) { printf("hfa384x: Tx FID allocate command failed: Aborting transmit..\n"); return; } if ( !hfa384x_wait_for_event(hw, HFA384x_EVSTAT_ALLOC, HFA384x_EVACK_INFO, 10, 50, "Tx FID to be allocated\n" ) ) return; fid = hfa384x_getreg(hw, HFA384x_ALLOCFID); /* Build Tx frame structure */ memset(&txdesc, 0, sizeof(txdesc)); txdesc.tx_control = host2hfa384x_16( HFA384x_TX_MACPORT_SET(0) | HFA384x_TX_STRUCTYPE_SET(1) | HFA384x_TX_TXEX_SET(1) | HFA384x_TX_TXOK_SET(1) ); txdesc.frame_control = host2ieee16( WLAN_SET_FC_FTYPE(WLAN_FTYPE_DATA) | WLAN_SET_FC_FSTYPE(WLAN_FSTYPE_DATAONLY) | WLAN_SET_FC_TODS(1) ); memcpy(txdesc.address1, hw->bssid, WLAN_ADDR_LEN); memcpy(txdesc.address2, nic->node_addr, WLAN_ADDR_LEN); memcpy(txdesc.address3, d, WLAN_ADDR_LEN); txdesc.data_len = host2hfa384x_16( sizeof(txdesc) + sizeof(p80211hdr) + s ); /* Set up SNAP header */ /* Let OUI default to RFC1042 (0x000000) */ p80211hdr.snap.type = htons(t); /* Copy txdesc, p80211hdr and payload parts to FID */ result = hfa384x_copy_to_bap(hw, fid, 0, &txdesc, sizeof(txdesc)); if ( result ) return; /* fail */ result = hfa384x_copy_to_bap( hw, fid, sizeof(txdesc), &p80211hdr, sizeof(p80211hdr) ); if ( result ) return; /* fail */ result = hfa384x_copy_to_bap( hw, fid, sizeof(txdesc) + sizeof(p80211hdr), (uint8_t*)p, s ); if ( result ) return; /* fail */ /* Issue Tx command */ result = hfa384x_docmd_wait(hw, HFA384x_CMD_CMDCODE_SET(HFA384x_CMDCODE_TX), fid, 0, 0); if ( result != 0 ) { printf("hfa384x: Transmit failed with result %#hx.\n", result); return; } /* Wait for transmit completion (or exception) */ result = hfa384x_wait_for_event(hw, HFA384x_EVSTAT_TXEXC | HFA384x_EVSTAT_TX, HFA384x_EVACK_INFO, 200, 500, "Tx to complete\n" ); if ( !result ) return; /* timeout failure */ if ( HFA384x_EVSTAT_ISTXEXC(result) ) { fid = hfa384x_getreg(hw, HFA384x_TXCOMPLFID); printf ( "Tx exception occurred with fid %#hx\n", fid ); result = hfa384x_copy_from_bap(hw, fid, 0, &status, sizeof(status)); if ( result ) return; /* fail */ printf("hfa384x: Tx error occurred (status %#hx):\n", status); if ( HFA384x_TXSTATUS_ISACKERR(status) ) { printf(" ...acknowledgement error\n"); } if ( HFA384x_TXSTATUS_ISFORMERR(status) ) { printf(" ...format error\n"); } if ( HFA384x_TXSTATUS_ISDISCON(status) ) { printf(" ...disconnected error\n"); } if ( HFA384x_TXSTATUS_ISAGEDERR(status) ) { printf(" ...AGED error\n"); } if ( HFA384x_TXSTATUS_ISRETRYERR(status) ) { printf(" ...retry error\n"); } return; /* fail */ } }