static void _WMI_SendEvent(wmi_handle_t handle, adf_nbuf_t pEvt, A_UINT16 EventId, A_UINT16 SeqNo, int Length) { WMI_SVC_CONTEXT *pWMI = (WMI_SVC_CONTEXT *)handle; A_UINT8 *pBuffer; pBuffer = adf_nbuf_push_head(pEvt, sizeof(WMI_CMD_HDR)); A_SET_UINT16_FIELD(pBuffer, WMI_CMD_HDR, commandId, adf_os_htons(EventId)); A_SET_UINT16_FIELD(pBuffer, WMI_CMD_HDR, seqNo, adf_os_htons(SeqNo)); HTC_SendMsg(pWMI->HtcHandle, pWMI->ControlEp, pEvt); }
A_STATUS HTCStart(HTC_HANDLE HTCHandle) { adf_nbuf_t netbuf; A_STATUS status = A_OK; HTC_TARGET *target = GET_HTC_TARGET_FROM_HANDLE(HTCHandle); HTC_SETUP_COMPLETE_MSG *SetupComp; AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Enter\n")); do { HTCConfigTargetHIFPipe(HTCHandle); #ifdef HTC_HOST_CREDIT_DIST adf_os_assert(target->InitCredits != NULL); adf_os_assert(target->EpCreditDistributionListHead != NULL); adf_os_assert(target->EpCreditDistributionListHead->pNext != NULL); /* call init credits callback to do the distribution , * NOTE: the first entry in the distribution list is ENDPOINT_0, so * we pass the start of the list after this one. */ target->InitCredits(target->pCredDistContext, target->EpCreditDistributionListHead->pNext, target->TargetCredits); #if 1 adf_os_timer_init(target->os_handle, &target->host_htc_credit_debug_timer, host_htc_credit_show, target); adf_os_timer_start(&target->host_htc_credit_debug_timer, 10000); #endif #endif /* allocate a buffer to send */ //netbuf = adf_nbuf_alloc(anet, sizeof(HTC_SETUP_COMPLETE_MSG), HTC_HDR_LENGTH, 0); netbuf = adf_nbuf_alloc(50, HTC_HDR_LENGTH, 0); if (netbuf == ADF_NBUF_NULL) { status = A_NO_MEMORY; break; } /* assemble setup complete message */ SetupComp = (HTC_SETUP_COMPLETE_MSG *)adf_nbuf_put_tail(netbuf, sizeof(HTC_SETUP_COMPLETE_MSG)); SetupComp->MessageID = adf_os_htons(HTC_MSG_SETUP_COMPLETE_ID); /* assemble the HTC header and send to HIF layer */ status = HTCIssueSend(target, ADF_NBUF_NULL, netbuf, 0, sizeof(HTC_SETUP_COMPLETE_MSG), ENDPOINT0); if (A_FAILED(status)) { break; } } while (FALSE); AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HTCStart Exit\n")); return status; }
a_status_t fwd_send_next(fwd_softc_t *sc) { a_uint32_t len, alloclen; adf_nbuf_t nbuf; fwd_cmd_t *h; a_uint8_t *pld; a_uint32_t target_jmp_loc; len = fwd_chunk_len(sc); alloclen = sizeof(fwd_cmd_t) + len; if (fwd_is_first(sc) || fwd_is_last(sc)) alloclen += 4; nbuf = adf_nbuf_alloc(NULL,alloclen + 20, 20, 0); if (!nbuf) { adf_os_print("FWD: packet allocation failed. \n"); return A_STATUS_ENOMEM; } h = (fwd_cmd_t *)adf_nbuf_put_tail(nbuf, alloclen); h->more_data = adf_os_htons(!fwd_is_last(sc)); h->len = adf_os_htons(len); h->offset = adf_os_htonl(sc->offset); pld = (a_uint8_t *)(h + 1); if (fwd_is_first(sc)) { *(a_uint32_t *)pld = adf_os_htonl(sc->target_upload_addr); pld += 4; } adf_os_mem_copy(pld, &sc->image[sc->offset], len); if(h->more_data == 0) { target_jmp_loc = adf_os_htonl(fw_exec_addr); adf_os_mem_copy(pld+len, (a_uint8_t *)&target_jmp_loc, 4); } HIFSend(sc->hif_handle, sc->tx_pipe, NULL, nbuf); /*adf_os_timer_start(&sc->tmr, FWD_TIMEOUT_MSECS);*/ return A_STATUS_OK; }
A_STATUS ConfigPipeCredits(HTC_TARGET *target, a_uint8_t pipeID, a_uint8_t credits) { A_STATUS status = A_OK; adf_nbuf_t netbuf; HTC_CONFIG_PIPE_MSG *CfgPipeCdt; do { /* allocate a buffer to send */ //netbuf = adf_nbuf_alloc(anet, sizeof(HTC_CONFIG_PIPE_MSG), HTC_HDR_LENGTH, 0); netbuf = adf_nbuf_alloc(50, HTC_HDR_LENGTH, 0); if (netbuf == ADF_NBUF_NULL) { status = A_NO_MEMORY; break; } /* assemble config pipe message */ CfgPipeCdt = (HTC_CONFIG_PIPE_MSG *)adf_nbuf_put_tail(netbuf, sizeof(HTC_CONFIG_PIPE_MSG)); CfgPipeCdt->MessageID = adf_os_htons(HTC_MSG_CONFIG_PIPE_ID); CfgPipeCdt->PipeID = pipeID; CfgPipeCdt->CreditCount = credits; /* assemble the HTC header and send to HIF layer */ #ifndef MAGPIE_SINGLE_CPU_CASE htc_spin_prep(&target->spin); #endif status = HTCIssueSend(target, ADF_NBUF_NULL, netbuf, 0, sizeof(HTC_CONFIG_PIPE_MSG), ENDPOINT0); if (A_FAILED(status)) { break; } htc_spin( &target->spin ); if (target->cfg_pipe_rsp_stat == HTC_CONFIGPIPE_SUCCESS) { status = A_OK; } else { status = A_ERROR; } } while(FALSE); return status; }
void __gmac_copy_ethhdr(ethhdr_t *dst, struct sk_buff *skb) { ethhdr_t *src = eth_hdr(skb); /** * Build the ethernet header for Xmit */ memcpy(dst->h_dest, src->h_source, ETH_ALEN); memcpy(dst->h_source, skb->dev->dev_addr, ETH_ALEN); dst->h_proto = adf_os_htons(ETH_P_ATH); }
A_STATUS HTCIssueSend(HTC_TARGET *target, adf_nbuf_t hdr_buf, adf_nbuf_t netbuf, a_uint8_t SendFlags, a_uint16_t len, a_uint8_t EpID) { a_uint8_t pipeID; A_STATUS status = A_OK; //adf_net_handle_t anet = target->pInstanceContext; HTC_ENDPOINT *pEndpoint = &target->EndPoint[EpID]; HTC_FRAME_HDR *HtcHdr; adf_nbuf_t tmp_nbuf; //printk("bharath %s \n",__FUNCTION__); if (hdr_buf == ADF_NBUF_NULL) { /* HTC header needs to be added on the data nbuf */ tmp_nbuf = netbuf; } else { tmp_nbuf = hdr_buf; } /* setup HTC frame header */ HtcHdr = (HTC_FRAME_HDR *)adf_nbuf_push_head(tmp_nbuf, sizeof(HTC_FRAME_HDR)); adf_os_assert(HtcHdr); if ( HtcHdr == NULL ) { adf_os_print("%s_%d: HTC Header is NULL !!!\n", __FUNCTION__, __LINE__); return A_ERROR; } HtcHdr->EndpointID = EpID; HtcHdr->Flags = SendFlags; HtcHdr->PayloadLen = adf_os_htons(len); HTC_ADD_CREDIT_SEQNO(target,pEndpoint,len,HtcHdr); /* lookup the pipe id by the endpoint id */ pipeID = pEndpoint->UL_PipeID; // if (EpID == ENDPOINT0) { /* send the buffer to the HIF layer */ status = HIFSend(target->hif_dev/*anet*/, pipeID, hdr_buf, netbuf); // } #ifdef NBUF_PREALLOC_POOL if ( A_FAILED(status) ) { adf_nbuf_pull_head(netbuf, HTC_HDR_LENGTH); } #endif return status; }
LOCAL void _HTC_Ready(htc_handle_t htcHandle) { adf_nbuf_t pBuffer; HTC_READY_MSG *pReady; a_uint8_t *addr; HTC_CONTEXT *pHTC = (HTC_CONTEXT *)htcHandle; pBuffer = HTCAllocMsgBuffer(pHTC); /* an optimization... the header length is chosen to * be aligned on a 16 bit bounday, the fields in the message are designed to * be aligned */ addr = adf_nbuf_put_tail(pBuffer, sizeof(HTC_READY_MSG)); pReady = (HTC_READY_MSG *)addr; A_MEMZERO(pReady,sizeof(HTC_READY_MSG)); pReady->MessageID = adf_os_htons(HTC_MSG_READY_ID); pReady->CreditSize = adf_os_htons((A_UINT16)pHTC->RecvBufferSize); pReady->CreditCount = adf_os_htons((A_UINT16)pHTC->TotalCredits); pReady->MaxEndpoints = ENDPOINT_MAX; /* send out the message */ HTC_SendMsg(pHTC, ENDPOINT0, pBuffer); /* now we need to wait for service connection requests */ }
LOCAL void HTCProcessConfigPipeMsg(HTC_CONTEXT *pHTC, HTC_CONFIG_PIPE_MSG *pMsg) { adf_nbuf_t pBuffer; HTC_CONFIG_PIPE_RESPONSE_MSG *pRspMsg; pBuffer = HTCAllocMsgBuffer(pHTC); /* note : this will be aligned */ pRspMsg = (HTC_CONFIG_PIPE_RESPONSE_MSG *) adf_nbuf_put_tail(pBuffer, sizeof(HTC_CONFIG_PIPE_RESPONSE_MSG)); A_MEMZERO(pRspMsg,sizeof(HTC_CONFIG_PIPE_RESPONSE_MSG)); pRspMsg->MessageID = adf_os_htons(HTC_MSG_CONFIG_PIPE_RESPONSE_ID); /* reflect the service ID for this connect attempt */ pRspMsg->PipeID = pMsg->PipeID; if ( HIF_is_pipe_supported(pHTC->hifHandle, pMsg->PipeID) ) { pRspMsg->Status = 0; } else { pRspMsg->Status = 1; goto config_done; } if ( (pHTC->TotalCreditsAssigned + pMsg->CreditCount) <= pHTC->TotalCredits ) { pHTC->TotalCreditsAssigned += pMsg->CreditCount; } else { pRspMsg->Status = 2; goto config_done; } HIF_config_pipe(pHTC->hifHandle, pMsg->PipeID, pMsg->CreditCount); config_done: /* send out the response message */ HTC_SendMsg(pHTC, ENDPOINT0, pBuffer); }
void fwd_parse_params(hif_gmac_params_t *params) { params->dump_pkt = dump_pkt ? adf_os_htons(1) : 0; if (dump_pkt) params->dump_pkt_lim = adf_os_htons(dump_pkt_lim); if (mac_addr) fwd_parse_str(mac_addr, params->mac_addr, ':', 6); else /* default */ fwd_parse_str(default_mac_addr, params->mac_addr, ':', 6); /* Parse the chip_type */ if (chip_type == ACT_MAC) params->chip_type = MII0_CTRL_TYPE_MAC; else /* default */ params->chip_type = MII0_CTRL_TYPE_PHY; /* Parse the link_speed */ if (link_speed == LINK_SPEED_10) params->link_speed = MII0_CTRL_SPEED_10; else if (link_speed == LINK_SPEED_100) params->link_speed = MII0_CTRL_SPEED_100; else /* default */ params->link_speed = MII0_CTRL_SPEED_1000; /* Parse the rgmii_delay */ if (rgmii_delay == RGMII_DELAY_NO) params->rgmii_delay = adf_os_htons(MII0_CTRL_RGMII_DELAY_NO); else if (rgmii_delay == RGMII_DELAY_SMALL) params->rgmii_delay = adf_os_htons(MII0_CTRL_RGMII_DELAY_SMALL); else if (rgmii_delay == RGMII_DELAY_MEDIUM) params->rgmii_delay = adf_os_htons(MII0_CTRL_RGMII_DELAY_MED); else /* default */ params->rgmii_delay = adf_os_htons(MII0_CTRL_RGMII_DELAY_HUGE); }
/* called in response to the arrival of a service connection message */ LOCAL void HTCProcessConnectMsg(HTC_CONTEXT *pHTC, HTC_CONNECT_SERVICE_MSG *pMsg) { HTC_SERVICE *pService = pHTC->pServiceList; A_UINT8 connectStatus = HTC_SERVICE_NOT_FOUND; adf_nbuf_t pBuffer; HTC_CONNECT_SERVICE_RESPONSE_MSG *pRspMsg; int metaDataOutLen = 0; A_UINT16 serviceId = adf_os_ntohs(pMsg->ServiceID); pBuffer = HTCAllocMsgBuffer(pHTC); /* note : this will be aligned */ pRspMsg = (HTC_CONNECT_SERVICE_RESPONSE_MSG *) adf_nbuf_put_tail(pBuffer, sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG)); A_MEMZERO(pRspMsg,sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG)); pRspMsg->MessageID = adf_os_htons(HTC_MSG_CONNECT_SERVICE_RESPONSE_ID); /* reflect the service ID for this connect attempt */ pRspMsg->ServiceID = adf_os_htons(serviceId); while (pService) { if (pHTC->CurrentEpIndex >= ENDPOINT_MAX) { /* no more endpoints */ connectStatus = HTC_SERVICE_NO_RESOURCES; break; } if (serviceId == pService->ServiceID) { /* we found a match */ A_UINT8 *pMetaDataIN = NULL; A_UINT8 *pMetaDataOut; /* outgoing meta data resides in the space after the response message */ pMetaDataOut = ((A_UINT8 *)pRspMsg) + sizeof(HTC_CONNECT_SERVICE_RESPONSE_MSG); if (pMsg->ServiceMetaLength != 0) { /* the meta data follows the connect service message */ pMetaDataIN = ((A_UINT8 *)pMsg) + sizeof(HTC_CONNECT_SERVICE_MSG); } /* call the connect callback with the endpoint to use and pointers to meta data */ connectStatus = pService->ProcessConnect(pService, pHTC->CurrentEpIndex, pMetaDataIN, pMsg->ServiceMetaLength, pMetaDataOut, &metaDataOutLen); /* check if the service accepted this connection request */ if (HTC_SERVICE_SUCCESS == connectStatus) { /* set the length of the response meta data going back to the host */ pRspMsg->ServiceMetaLength = (A_UINT8)metaDataOutLen; /* set the endpoint ID the host will now communicate over */ pRspMsg->EndpointID = pHTC->CurrentEpIndex; /* return the maximum message size for this service */ pRspMsg->MaxMsgSize = adf_os_htons((A_UINT16)pService->MaxSvcMsgSize); /* assign this endpoint to this service, this will be used in routing messages */ pHTC->Endpoints[pHTC->CurrentEpIndex].pService = pService; /* set connection flags */ pHTC->Endpoints[pHTC->CurrentEpIndex].ConnectionFlags = pMsg->ConnectionFlags; pHTC->Endpoints[pHTC->CurrentEpIndex].DownLinkPipeID = pMsg->DownLinkPipeID; pHTC->Endpoints[pHTC->CurrentEpIndex].UpLinkPipeID = pMsg->UpLinkPipeID; /* mark that we are now connected */ pService->ServiceFlags |= HTC_SERVICE_FLAGS_CONNECTED; /* bump up our index, this EP is now in use */ pHTC->CurrentEpIndex++; } break; } pService = pService->pNext; } pRspMsg->Status = connectStatus; /* send out the response message */ HTC_SendMsg(pHTC, ENDPOINT0, pBuffer); }
LOCAL void _HTC_SendMsg(htc_handle_t htcHandle, HTC_ENDPOINT_ID EndpointID, adf_nbuf_t pBuffers) { HTC_FRAME_HDR *pHTCHdr; int totsz; HTC_CONTEXT *pHTC = (HTC_CONTEXT *)htcHandle; HTC_BUF_CONTEXT *ctx; ctx = (HTC_BUF_CONTEXT *)adf_nbuf_get_priv(pBuffers); /* init total size (this does not include the space we will put in for the HTC header) */ totsz = adf_nbuf_len(pBuffers); /* the first buffer stores the header */ /* back up buffer by a header size when we pass it down, by agreed upon convention the caller * points the buffer to it's payload and leaves head room for the HTC header * Note: in HTCSendDoneHandler(), we undo this so that the caller get's it's buffer * back untainted */ pHTCHdr = (HTC_FRAME_HDR *)adf_nbuf_push_head(pBuffers, HTC_HDR_LENGTH); /* flag that this is the header buffer that was modified */ ctx->htc_flags |= HTC_FLAGS_BUF_HDR; /* mark where this buffer came from */ ctx->end_point = EndpointID; /* the header start is ALWAYS aligned since we DMA it directly */ /* set some fields, the rest of them will be filled below when we check for * trailer space */ pHTCHdr->Flags = 0; pHTCHdr->EndpointID = EndpointID; /* check opportunistically if we can return any reports via a trailer */ do { int room,i,totalReportBytes; A_UINT32 creditsPendingMap, compareMask; HTC_CREDIT_REPORT *pCreditRpt; HTC_RECORD_HDR *pRecHdr; int pipeMaxLen; A_UINT32 roomForPipeMaxLen; /* figure out how much room the last buffer can spare */ pipeMaxLen = HIF_get_max_msg_len(pHTC->hifHandle, pHTC->Endpoints[EndpointID].DownLinkPipeID); roomForPipeMaxLen = pipeMaxLen - adf_nbuf_headroom(pBuffers) - adf_nbuf_len(pBuffers); if ( roomForPipeMaxLen < 0 ) { roomForPipeMaxLen = 0; } room = adf_os_min( adf_nbuf_tailroom(pBuffers), roomForPipeMaxLen); if (room < (int)(sizeof(HTC_CREDIT_REPORT) + sizeof(HTC_RECORD_HDR))) { /* no room for any reports */ break; } /* note, a record header only has 8 bit fields, so this is safe. * we need an uncached pointer here too */ totalReportBytes = 0; /* get a copy */ creditsPendingMap = pHTC->EpCreditPendingMap; /* test pending map to see if we can send a report , if any * credits are available, we might as well send them on the * unused space in the buffer */ if (creditsPendingMap) { pRecHdr = (HTC_RECORD_HDR *)adf_nbuf_put_tail(pBuffers, sizeof(HTC_RECORD_HDR)); /* set the ID, the length will be updated with the number of credit reports we * can fit (see below) */ pRecHdr->RecordID = HTC_RECORD_CREDITS; pRecHdr->Length = 0; /* the credit report follows the record header */ totalReportBytes += sizeof(HTC_RECORD_HDR); room -= sizeof(HTC_RECORD_HDR); /* walkthrough pending credits map and build the records */ for (i = 0; (creditsPendingMap != 0) && (room >= (int)sizeof(HTC_CREDIT_REPORT)); i++) { compareMask = (1 << i); if (compareMask & creditsPendingMap) { pCreditRpt = (HTC_CREDIT_REPORT *)adf_nbuf_put_tail(pBuffers, sizeof(HTC_CREDIT_REPORT)); /* clear pending mask, we are going to return all these credits */ creditsPendingMap &= ~(compareMask); /* add this record */ pCreditRpt->EndpointID = i; pCreditRpt->Credits = (A_UINT8)pHTC->Endpoints[i].CreditsToReturn; /* remove pending credits, we always send deltas */ pHTC->Endpoints[i].CreditsToReturn = 0; /* adjust new threshold for this endpoint if needed */ CHECK_AND_ADJUST_CREDIT_THRESHOLD(&pHTC->Endpoints[i]); /* update this record length */ pRecHdr->Length += sizeof(HTC_CREDIT_REPORT); room -= sizeof(HTC_CREDIT_REPORT); totalReportBytes += sizeof(HTC_CREDIT_REPORT); if ( room < sizeof(HTC_CREDIT_REPORT) ) { break; } } } /* update new pending credits map */ pHTC->EpCreditPendingMap = creditsPendingMap; } if (totalReportBytes <= 0) { break; } /* must fit into a byte, this should never actually happen since * the maximum possible number of endpoints is 32. * The trailer can have at most 1 credit record with up to 32 reports in the record. * The trailer can have at most 1 lookahead record with only 1 lookahead report in the record. */ /* set header option bytes */ pHTCHdr->ControlBytes[0] = totalReportBytes; /* HTC frame contains a trailer */ pHTCHdr->Flags |= HTC_FLAGS_RECV_TRAILER; /* increment total size by the reports we added */ totsz += totalReportBytes; /* adjust the last buffer we used for adding on the trailer */ } while (FALSE); if (totsz == 0) { } /* set length for message (this includes any reports that were added above) */ pHTCHdr->PayloadLen = adf_os_htons(totsz); HIF_send_buffer(pHTC->hifHandle, pHTC->Endpoints[EndpointID].DownLinkPipeID, pBuffers); }