/* WMI command API */ int wmi_unified_cmd_send(wmi_unified_t wmi_handle, wmi_buf_t buf, int len, WMI_CMD_ID cmd_id) { A_STATUS status; struct cookie *cookie; if (wbuf_push(buf, sizeof(WMI_CMD_HDR)) == NULL) { wbuf_free(buf); return -ENOMEM; } if (wmi_handle->wmi_stopinprogress) { printk("WMI stop in progress \n"); wbuf_free(buf); return -ENOMEM; } WMI_SET_FIELD(wbuf_header(buf), WMI_CMD_HDR, COMMANDID, cmd_id); //WMI_CMD_HDR_SET_DEVID(cmd_hdr, 0); // unused cookie = ol_alloc_cookie(wmi_handle->scn_handle); if (!cookie) { printk("%s : Cookie alloc Failed for cmd_id : %0x \n",__func__,cmd_id); wbuf_free(buf); return -ENOMEM; } cookie->PacketContext = buf; SET_HTC_PACKET_INFO_TX(&cookie->HtcPkt, cookie, wbuf_header(buf), len+sizeof(WMI_CMD_HDR), /* htt_host_data_dl_len(buf)+20 */ wmi_handle->wmi_endpoint_id, 0/*htc_tag*/); SET_HTC_PACKET_NET_BUF_CONTEXT(&cookie->HtcPkt, buf); status = HTCSendPkt(wmi_handle->htc_handle, &cookie->HtcPkt); if (status != A_OK) { ol_free_cookie(wmi_handle->scn_handle, cookie); wbuf_free(buf); } return ((status == A_OK) ? EOK : -1); }
/* * Temporarily added to support older WMI events. We should move all events to unified * when the target is ready to support it. */ void wmi_control_rx(void *ctx, HTC_PACKET *htc_packet) { u_int16_t id; u_int8_t *data; u_int32_t len; int status = EOK; wmi_buf_t evt_buf; struct wmi_unified *wmi_handle = (struct wmi_unified *) ctx; evt_buf = (wmi_buf_t) htc_packet->pPktContext; /** * This is a HACK due to a Hack/WAR in HTC !!. * the head of the wbuf still contains the HTC header * but the length excludes htc header. */ wbuf_set_pktlen(evt_buf, htc_packet->ActualLength + HTC_HEADER_LEN); wbuf_pull(evt_buf, HTC_HEADER_LEN); id = WMI_GET_FIELD(wbuf_header(evt_buf), WMI_CMD_HDR, COMMANDID); if ((id >= WMI_START_EVENTID) && (id <= WMI_END_EVENTID)) { status = wmi_unified_event_rx(wmi_handle, evt_buf); return ; } if (wbuf_pull(evt_buf, sizeof(WMI_CMD_HDR)) == NULL) { status = -1; goto end; } data = wbuf_header(evt_buf); len = wbuf_get_pktlen(evt_buf); switch(id) { default: printk("%s: Unhandled WMI command %d\n", __func__, id); break; case WMI_SERVICE_READY_EVENTID: status = wmi_service_ready_event_rx(wmi_handle, data, len); break; case WMI_READY_EVENTID: status = wmi_ready_event_rx(wmi_handle, data, len); break; case WMI_WLAN_VERSION_EVENTID: printk("%s: Handle WMI_VERSION_EVENTID\n", __func__); break; case WMI_REGDOMAIN_EVENTID: printk("%s: Handle WMI_REGDOMAIN_EVENTID\n", __func__); break; case WMI_DEBUG_MESG_EVENTID: dbglog_message_handler(wmi_handle->scn_handle, evt_buf); return; } end: wbuf_free(evt_buf); }
int ieee80211_crypto_handle_keymiss(struct ieee80211com *ic, wbuf_t wbuf, struct ieee80211_rx_status *rs) { struct ieee80211_node *ni = NULL; /* * Handle packets with keycache miss */ if ((rs->rs_flags & IEEE80211_RX_KEYMISS)) { ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wbuf_header(wbuf)); if( ni != NULL) { struct ieee80211vap *vap = ni->ni_vap; ieee80211_key_update_begin(vap); if (!ieee80211_crypto_keymiss(ni, wbuf, rs)) { IEEE80211_DPRINTF(vap, IEEE80211_MSG_CRYPTO, "%s: Couldn't decrypt, dropping packet.\n", __func__); wbuf_free(wbuf); ieee80211_key_update_end(vap); ieee80211_free_node(ni); return 1; }else { ieee80211_key_update_end(vap); ieee80211_free_node(ni); } } } return 0; }
void wmi_htc_tx_complete(void *ctx,HTC_PACKET *htc_pkt) { wmi_buf_t wmi_cmd_buf=GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt); struct cookie *cookie = htc_pkt->pPktContext; ASSERT(wmi_cmd_buf); wbuf_free(wmi_cmd_buf); ol_free_cookie(ctx, cookie); }
void wmi_htc_tx_complete(void *ctx,HTC_PACKET *htc_pkt) { wmi_buf_t wmi_cmd_buf=GET_HTC_PACKET_NET_BUF_CONTEXT(htc_pkt); struct wmi_unified *wmi_handle = (struct wmi_unified *)ctx; struct cookie *cookie = htc_pkt->pPktContext; ASSERT(wmi_cmd_buf); wbuf_free(wmi_cmd_buf); ol_free_cookie(wmi_handle->scn_handle , cookie); return; }
static int wmi_unified_event_rx(struct wmi_unified *wmi_handle, wmi_buf_t evt_buf) { u_int16_t id; u_int8_t *event; u_int16_t len; int status = -1; u_int16_t handler_id; ASSERT(evt_buf != NULL); id = WMI_GET_FIELD(wbuf_header(evt_buf), WMI_CMD_HDR, COMMANDID); handler_id = (id - WMI_START_EVENTID); if (wbuf_pull(evt_buf, sizeof(WMI_CMD_HDR)) == NULL) { //A_DPRINTF(DBG_WMI, (DBGFMT "bad packet 1\n", DBGARG)); //wmip->wmi_stats.cmd_len_err++; goto end; } if (handler_id >= WMI_UNIFIED_MAX_EVENT) { printk("%s : unkown event id : 0x%x event handler id 0x%x \n", __func__, id, handler_id); goto end; } event = wbuf_header(evt_buf); len = wbuf_get_pktlen(evt_buf); if (!wmi_handle->event_handler[handler_id]) { printk("%s : no registered event handler : event id 0x%x \n", __func__, id); goto end; } /* Call the WMI registered event handler */ status = wmi_handle->event_handler[handler_id](wmi_handle->scn_handle, event, len, wmi_handle->event_handler_cookie[handler_id]); end: wbuf_free(evt_buf); return status; }
void _ath_htc_netdeferfn_cleanup(struct ieee80211com *ic) { wbuf_t wbuf = ADF_NBUF_NULL ; nawds_dentry_t * nawds_entry = NULL ; /* Freeing MGMT defer buffer */ do { OS_MGMT_LOCKBH(&ic->ic_mgmt_lock); wbuf = adf_nbuf_queue_remove(&ic->ic_mgmt_nbufqueue); OS_MGMT_UNLOCKBH(&ic->ic_mgmt_lock); if(!wbuf) break; wbuf_free(wbuf); }while(wbuf); atomic_set(&ic->ic_mgmt_deferflags, DEFER_DONE); do { OS_NAWDSDEFER_LOCKBH(&ic->ic_nawdsdefer_lock); nawds_entry = TAILQ_FIRST(&ic->ic_nawdslearnlist); if(nawds_entry) TAILQ_REMOVE(&ic->ic_nawdslearnlist,nawds_entry,nawds_dlist); OS_NAWDSDEFER_UNLOCKBH(&ic->ic_nawdsdefer_lock); if(!nawds_entry) break; OS_FREE(nawds_entry); }while(1); atomic_set(&ic->ic_nawds_deferflags, DEFER_DONE); }
static int ath_rx_assemble_buf(struct ath_softc *sc, wbuf_t *wbuf, ieee80211_rx_status_t *status, u_int16_t keyix) { struct ath_buf *bf = NULL; struct sk_buff *kb = NULL; wbuf_t nwbuf; if (wbuf_next(*wbuf)) { /* for linux multiple receive buffer */ bf = ATH_GET_RX_CONTEXT_BUF(wbuf_next(*wbuf)); bf->bf_mpdu = wbuf_next(*wbuf); /* unlink the top half buffer and bottom half buffer */ wbuf_setnextpkt(*wbuf, NULL); /* use skb_copy_expand for combining two buffer, nwbuf = wbuf##twbuf */ nwbuf = skb_copy_expand((struct sk_buff *)*wbuf, 0, wbuf_get_pktlen(*wbuf)+wbuf_get_pktlen(bf->bf_mpdu), GFP_ATOMIC); if (nwbuf != NULL) { skb_copy_bits(bf->bf_mpdu, 0, wbuf_header(nwbuf) + wbuf_get_pktlen(*wbuf), wbuf_get_pktlen(bf->bf_mpdu)); kb = (struct sk_buff *)nwbuf; ((struct ieee80211_cb *)kb->cb)->context = &(((struct ieee80211_cb *)kb->cb)[1]); skb_put(nwbuf,wbuf_get_pktlen(bf->bf_mpdu)); wbuf_free(bf->bf_mpdu); bf->bf_mpdu = nwbuf; ATH_SET_RX_CONTEXT_BUF(nwbuf, bf); } else { ATH_GET_RX_CONTEXT_BUF(*wbuf)->bf_status |= ATH_BUFSTATUS_FREE; if (sc->sc_enhanceddmasupport) { wbuf_push(*wbuf, sc->sc_rxstatuslen); wbuf_push(bf->bf_mpdu, sc->sc_rxstatuslen); } wbuf_trim(bf->bf_mpdu, wbuf_get_pktlen(bf->bf_mpdu)); wbuf_trim(*wbuf, wbuf_get_pktlen(*wbuf)); bf->bf_buf_addr[0] = wbuf_map_single(sc->sc_osdev, bf->bf_mpdu, BUS_DMA_FROMDEVICE, OS_GET_DMA_MEM_CONTEXT(bf, bf_dmacontext)); /* relink unused wbuf to H/W */ ath_rx_requeue(sc, *wbuf); ath_rx_requeue(sc, bf->bf_mpdu); return -1; } ATH_GET_RX_CONTEXT_BUF(*wbuf)->bf_status |= ATH_BUFSTATUS_FREE; if (sc->sc_enhanceddmasupport) { wbuf_push(*wbuf, sc->sc_rxstatuslen); } wbuf_trim(*wbuf, wbuf_get_pktlen(*wbuf)); /* relink unused wbuf to H/W */ ath_rx_requeue(sc, *wbuf); *wbuf = bf->bf_mpdu; } return 0; }