示例#1
0
/* 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);
}
示例#2
0
/*
 * 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;
}
示例#4
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);
}
示例#5
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 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;
}
示例#6
0
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;
}
示例#7
0
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);

}
示例#8
0
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;

}