uint8_t sd_cmd(uint8_t cmd, uint32_t arg) { uint8_t i; uint8_t r; sd_recv(); // skip some bytes sd_send(0x40 | cmd); sd_send((arg >> 24) & 0xff); sd_send((arg >> 16) & 0xff); sd_send((arg >> 8) & 0xff); sd_send(arg & 0xff); switch (cmd) { case CMD_GO_IDLE_STATE: sd_send(0x95); break; case CMD_SEND_IF_COND: sd_send(0x87); break; default: sd_send(0xff); } for (i = 0; i < 10; i++) { if ((r = sd_recv()) != 0xff) break; } return r; }
u8 send_cmd_packet(struct net_adapter *adapter, u16 cmd_id) { struct hw_packet_header *pkt_hdr; struct wimax_msg_header *msg_hdr; u8 tx_buf[CMD_MSG_TOTAL_LENGTH]; int status = 0; u32 offset; u32 size; pkt_hdr = (struct hw_packet_header *)tx_buf; pkt_hdr->id0 = 'W'; pkt_hdr->id1 = 'C'; pkt_hdr->length = be16_to_cpu(CMD_MSG_TOTAL_LENGTH); offset = sizeof(struct hw_packet_header); msg_hdr = (struct wimax_msg_header *)(tx_buf + offset); msg_hdr->type = be16_to_cpu(ETHERTYPE_DL); msg_hdr->id = be16_to_cpu(cmd_id); msg_hdr->length = be32_to_cpu(CMD_MSG_LENGTH); size = CMD_MSG_TOTAL_LENGTH; status = sd_send(adapter, tx_buf, size); if (status != STATUS_SUCCESS) { /* crc error or data error - set PCWRT '1' & send current type A packet again */ dump_debug("hwSdioWrite : crc or data error"); return status; } return status; }
BOOLEAN SendCmdPacket(PMINIPORT_ADAPTER Adapter, unsigned short uiCmdId) { PHW_PACKET_HEADER pPktHdr; UCHAR pTxPkt[CMD_MSG_TOTAL_LENGTH]; UINT uiBufOffset; PWIMAX_MESSAGE_HEADER pWibroMsgHdr; int status = 0; UINT dwTxSize; pPktHdr = (PHW_PACKET_HEADER)pTxPkt; pPktHdr->Id0 = 'W'; pPktHdr->Id1 = 'C'; pPktHdr->Length = be16_to_cpu(CMD_MSG_TOTAL_LENGTH); uiBufOffset = sizeof(HW_PACKET_HEADER); pWibroMsgHdr = (PWIMAX_MESSAGE_HEADER)(pTxPkt + uiBufOffset); pWibroMsgHdr->MsgType = be16_to_cpu(ETHERTYPE_DL); pWibroMsgHdr->MsgID = be16_to_cpu(uiCmdId); pWibroMsgHdr->MsgLength = be32_to_cpu(CMD_MSG_LENGTH); dwTxSize = CMD_MSG_TOTAL_LENGTH; status = sd_send(Adapter, pTxPkt, dwTxSize); if(status != STATUS_SUCCESS) { // crc error or data error - set PCWRT '1' & send current type A packet again DumpDebug(FW_DNLD, "hwSdioWrite : crc error"); return status;//goto rewrite; } return status; }
/* get MAC address from device */ VOID GetMacAddress(MINIPORT_ADAPTER *Adapter) { UINT nCount = 0; int nResult = 0; HW_PRIVATE_PACKET req; ENTER; req.Id0 = 'W'; req.Id1 = 'P'; req.Code = HwCodeMacRequest; req.Value = 0; Adapter->acquired_mac_address = FALSE; do { if(Adapter->bHaltPending) return; sdio_claim_host(Adapter->func); //nResult = sdio_memcpy_toio(Adapter->func,SDIO_DATA_PORT_REG, &req, sizeof(HW_PRIVATE_PACKET)); nResult = sd_send(Adapter, &req, sizeof(HW_PRIVATE_PACKET)); if(nResult != 0) DumpDebug(DRV_ENTRY,"Send GetMacAddress Request msg but error occurred!! res = %d",nResult); sdio_release_host(Adapter->func); if(!wait_for_completion_interruptible_timeout(&Adapter->hFWInitCompleteEvent, msecs_to_jiffies(HARDWARE_START_TIMEOUT))) { DumpDebug(DRV_ENTRY, "timedout mac req, retry.."); if(nCount >= HARDWARE_MAX_MAC_RESPONSES || Adapter->bHaltPending == TRUE) { DumpDebug(DRV_ENTRY,"Can't get mac address, exceeded number of retries (%d)",nCount); Adapter->bHaltPending = TRUE; wake_up_interruptible(&Adapter->hFWDNEndEvent); gpio_wimax_poweroff(); gpio_wimax_poweron(); break; } nCount++; continue; } // If wait exit before timeout then mac assigned or surprise remove if(Adapter->acquired_mac_address == TRUE) { DumpDebug(DRV_ENTRY,"MAC Address acquired"); break; } // msleep(500); } while(TRUE); return; LEAVE; }
u8 send_image_info_packet(struct net_adapter *adapter, u16 cmd_id) { struct hw_packet_header *pkt_hdr; struct wimax_msg_header *msg_hdr; u32 image_info[4]; u8 tx_buf[IMAGE_INFO_MSG_TOTAL_LENGTH]; int status; u32 offset; u32 size; pkt_hdr = (struct hw_packet_header *)tx_buf; pkt_hdr->id0 = 'W'; pkt_hdr->id1 = 'C'; pkt_hdr->length = be16_to_cpu(IMAGE_INFO_MSG_TOTAL_LENGTH); offset = sizeof(struct hw_packet_header); msg_hdr = (struct wimax_msg_header *)(tx_buf + offset); msg_hdr->type = be16_to_cpu(ETHERTYPE_DL); msg_hdr->id = be16_to_cpu(cmd_id); msg_hdr->length = be32_to_cpu(IMAGE_INFO_MSG_LENGTH); image_info[0] = 0; image_info[1] = be32_to_cpu(g_wimax_image.size); image_info[2] = be32_to_cpu(g_wimax_image.address); image_info[3] = 0; offset += sizeof(struct wimax_msg_header); memcpy(&(tx_buf[offset]), image_info, sizeof(image_info)); size = IMAGE_INFO_MSG_TOTAL_LENGTH; status = sd_send(adapter, tx_buf, size); if (status != STATUS_SUCCESS) { /* * crc error or data error - * set PCWRT '1' & send current type A packet again */ dump_debug("hwSdioWrite : crc error"); return status; } return status; }
BOOLEAN SendImageInfoPacket(PMINIPORT_ADAPTER Adapter, unsigned short uiCmdId) { PHW_PACKET_HEADER pPktHdr; UCHAR pTxPkt[IMAGE_INFO_MSG_TOTAL_LENGTH]; UINT pImageInfo[4]; UINT uiBufOffset; PWIMAX_MESSAGE_HEADER pWibroMsgHdr; int status; UINT dwTxSize; pPktHdr = (PHW_PACKET_HEADER)pTxPkt; pPktHdr->Id0 = 'W'; pPktHdr->Id1 = 'C'; pPktHdr->Length = be16_to_cpu(IMAGE_INFO_MSG_TOTAL_LENGTH); uiBufOffset = sizeof(HW_PACKET_HEADER); pWibroMsgHdr = (PWIMAX_MESSAGE_HEADER)(pTxPkt + uiBufOffset); pWibroMsgHdr->MsgType = be16_to_cpu(ETHERTYPE_DL); pWibroMsgHdr->MsgID = be16_to_cpu(uiCmdId); pWibroMsgHdr->MsgLength = be32_to_cpu(IMAGE_INFO_MSG_LENGTH); pImageInfo[0] = 0; pImageInfo[1] = be32_to_cpu(g_stWiMAXImage.uiSize); pImageInfo[2] = be32_to_cpu(g_stWiMAXImage.uiWorkAddress); pImageInfo[3] = 0; uiBufOffset += sizeof(WIMAX_MESSAGE_HEADER); memcpy(&(pTxPkt[uiBufOffset]), pImageInfo, sizeof(pImageInfo)); dwTxSize = IMAGE_INFO_MSG_TOTAL_LENGTH; status = sd_send(Adapter, pTxPkt, dwTxSize); if(status != STATUS_SUCCESS) { // crc error or data error - set PCWRT '1' & send current type A packet again DumpDebug(FW_DNLD, "hwSdioWrite : crc error"); return status;//goto rewrite; } return status; }
/* get MAC address from device */ void hw_get_mac_address(void *data) { struct net_adapter *adapter = (struct net_adapter *)data; struct hw_private_packet req; int nResult = 0; int retry = 3; req.id0 = 'W'; req.id1 = 'P'; req.code = HwCodeMacRequest; req.value = 0; do { if (adapter == NULL) break; sdio_claim_host(adapter->func); nResult = sd_send(adapter, (u_char *)&req, sizeof(struct hw_private_packet)); sdio_release_host(adapter->func); if (nResult != STATUS_SUCCESS) dump_debug("hw_get_mac_address: sd_send fail!!"); msleep(300); retry--; /*in case we dont get MAC we need to release power lock and probe finsh */ if (!retry) { adapter->download_complete = TRUE; wake_up_interruptible(&adapter->download_event); msleep(100); } } while ((!adapter->mac_ready) && (!adapter->halted) && retry); adapter->pdata->g_cfg->powerup_done = true ; dump_debug("MAC thread exit"); return; }
void hw_transmit_thread(struct work_struct *work) { struct buffer_descriptor *dsc; struct hw_private_packet hdr; struct net_adapter *adapter; int nRet = 0; adapter = container_of(work, struct net_adapter, transmit_work); struct wimax_cfg *g_cfg = adapter->pdata->g_cfg; wake_lock_timeout(&g_cfg->wimax_rxtx_lock, 0.2 * HZ); mutex_lock(&adapter->rx_lock); if (!gpio_get_value(WIMAX_EN)) { dump_debug("WiMAX Power OFF!! (TX)"); adapter->halted = TRUE; return; } /* prevent WiMAX modem suspend during tx phase */ mutex_lock(&g_cfg->suspend_mutex); hw_device_wakeup(adapter); while (!queue_empty(adapter->hw.q_send.head)) { if (adapter->halted) { /* send stop message */ hdr.id0 = 'W'; hdr.id1 = 'P'; hdr.code = HwCodeHaltedIndication; hdr.value = 0; if (sd_send(adapter, (unsigned char *)&hdr, sizeof(struct hw_private_packet))) dump_debug("halted," " send HaltIndication to FW err"); break; } dsc = (struct buffer_descriptor *) queue_get_head(adapter->hw.q_send.head); if (!dsc->buffer) { dump_debug("dsc->buffer is NULL"); break; } if (!dsc) { dump_debug("Fail...node is null"); mutex_unlock(&g_cfg->suspend_mutex); break; } sdio_claim_host(adapter->func); nRet = sd_send_data(adapter, dsc); sdio_release_host(adapter->func); queue_remove_head(adapter->hw.q_send.head); kfree(dsc->buffer); kfree(dsc); if (nRet != STATUS_SUCCESS) { dump_debug("SendData Fail******"); ++adapter->XmitErr; if (nRet == -ENOMEDIUM || nRet == /*-ETIMEOUT*/-110) { adapter->halted = TRUE; break; } } } mutex_unlock(&g_cfg->suspend_mutex); mutex_unlock(&adapter->rx_lock); return ; }
u8 send_image_data_packet(struct net_adapter *adapter, u16 cmd_id) { struct hw_packet_header *pkt_hdr; struct image_data_payload *pImageDataPayload; struct wimax_msg_header *msg_hdr; u8 *tx_buf = NULL; int status; u32 len; u32 offset; u32 size; tx_buf = kmalloc(MAX_IMAGE_DATA_MSG_LENGTH, GFP_KERNEL); if (tx_buf == NULL) { dump_debug("MALLOC FAIL!!"); return -1; } pkt_hdr = (struct hw_packet_header *)tx_buf; pkt_hdr->id0 = 'W'; pkt_hdr->id1 = 'C'; offset = sizeof(struct hw_packet_header); msg_hdr = (struct wimax_msg_header *)(tx_buf + offset); msg_hdr->type = be16_to_cpu(ETHERTYPE_DL); msg_hdr->id = be16_to_cpu(cmd_id); if (g_wimax_image.offset < (g_wimax_image.size - MAX_IMAGE_DATA_LENGTH)) len = MAX_IMAGE_DATA_LENGTH; else len = g_wimax_image.size - g_wimax_image.offset; offset += sizeof(struct wimax_msg_header); pImageDataPayload = (struct image_data_payload *)(tx_buf + offset); pImageDataPayload->offset = be32_to_cpu(g_wimax_image.offset); pImageDataPayload->size = be32_to_cpu(len); memcpy(pImageDataPayload->data, g_wimax_image.data + g_wimax_image.offset, len); size = len + 8; /* length of Payload offset + length + data */ pkt_hdr->length = be16_to_cpu(CMD_MSG_TOTAL_LENGTH + size); msg_hdr->length = be32_to_cpu(size); size = CMD_MSG_TOTAL_LENGTH + size; status = sd_send(adapter, tx_buf, size); if (status != STATUS_SUCCESS) { /* crc error or data error - * set PCWRT '1' & send current type A packet again */ dump_debug("hwSdioWrite : crc error"); kfree(tx_buf); return status; } g_wimax_image.offset += len; kfree(tx_buf); return status; }
BOOLEAN SendImageDataPacket(PMINIPORT_ADAPTER Adapter, unsigned short uiCmdId) { PHW_PACKET_HEADER pPktHdr; UCHAR pTxPkt[MAX_IMAGE_DATA_MSG_LENGTH]; UINT uiPayloadSize; UINT uiBufOffset; UINT uiImageLength; PIMAGE_DATA_PAYLOAD pImageDataPayload; PWIMAX_MESSAGE_HEADER pWibroMsgHdr; int status; UINT dwTxSize; pPktHdr = (PHW_PACKET_HEADER)pTxPkt; pPktHdr->Id0 = 'W'; pPktHdr->Id1 = 'C'; uiBufOffset = sizeof(HW_PACKET_HEADER); pWibroMsgHdr = (PWIMAX_MESSAGE_HEADER)(pTxPkt + uiBufOffset); pWibroMsgHdr->MsgType = be16_to_cpu(ETHERTYPE_DL); pWibroMsgHdr->MsgID = be16_to_cpu(uiCmdId); if(g_stWiMAXImage.uiOffset < (g_stWiMAXImage.uiSize - MAX_IMAGE_DATA_LENGTH)) uiImageLength = MAX_IMAGE_DATA_LENGTH; else uiImageLength = g_stWiMAXImage.uiSize - g_stWiMAXImage.uiOffset; uiBufOffset += sizeof(WIMAX_MESSAGE_HEADER); pImageDataPayload = (PIMAGE_DATA_PAYLOAD)(pTxPkt + uiBufOffset); pImageDataPayload->uiOffset = be32_to_cpu( g_stWiMAXImage.uiOffset); pImageDataPayload->uiLength = be32_to_cpu(uiImageLength); memcpy(pImageDataPayload->ucImageData, g_stWiMAXImage.pImage + g_stWiMAXImage.uiOffset, uiImageLength); uiPayloadSize = uiImageLength + 8; // PayloadÀÇ Offset + Length + ImageData ±æÀÌ pPktHdr->Length = be16_to_cpu(CMD_MSG_TOTAL_LENGTH + uiPayloadSize); pWibroMsgHdr->MsgLength = be32_to_cpu(uiPayloadSize); dwTxSize = CMD_MSG_TOTAL_LENGTH + uiPayloadSize; #if 0 { // dump packets UINT i, l = dwTxSize; RETAILMSG(1, (TEXT("Send Image Data packet [%d] = "), l)); for (i = 0; i < l; i++) { RETAILMSG(1, (TEXT("%02x"), pTxPkt[i])); if (i != (l - 1)) RETAILMSG(1, (_T(","))); if ((i != 0) && ((i%32) == 0)) RETAILMSG(1, (_T("\n"))); } RETAILMSG(1, (_T("\n"))); } #endif status = sd_send(Adapter, pTxPkt, dwTxSize); if(status != STATUS_SUCCESS) { // crc error or data error - set PCWRT '1' & send current type A packet again DumpDebug(FW_DNLD, "hwSdioWrite : crc error"); return status;//goto rewrite; } g_stWiMAXImage.uiOffset += uiImageLength; return status; }