/**************************************************** * Invoked from bluetooth stack via hdev->send() * to send the packet out via ar6k to PAL firmware. * * For HCI command packet wmi_send_hci_cmd() is invoked. * wmi_send_hci_cmd adds WMI_CMD_HDR and sends the packet * to PAL firmware. * * For HCI ACL data packet wmi_data_hdr_add is invoked * to add WMI_DATA_HDR to the packet. ar6000_acl_data_tx * is then invoked to send the packet to PAL firmware. ******************************************************/ static int btpal_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *)skb->dev; HCI_TRANSPORT_PACKET_TYPE type; ar6k_hci_pal_info_t *pHciPalInfo; A_STATUS status = A_OK; struct sk_buff *txSkb = NULL; AR_SOFTC_DEV_T *ar; if (!hdev) { PRIN_LOG("HCI PAL: btpal_send_frame - no device\n"); return -ENODEV; } if (!test_bit(HCI_RUNNING, &hdev->flags)) { PRIN_LOG("HCI PAL: btpal_send_frame - not open\n"); return -EBUSY; } pHciPalInfo = (ar6k_hci_pal_info_t *)hdev->driver_data; A_ASSERT(pHciPalInfo != NULL); ar = pHciPalInfo->ar; PRIN_LOG("+btpal_send_frame type: %d \n",bt_cb(skb)->pkt_type); type = HCI_COMMAND_TYPE; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: type = HCI_COMMAND_TYPE; hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: type = HCI_ACL_TYPE; hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: /* we don't support SCO over the pal */ kfree_skb(skb); return 0; default: A_ASSERT(FALSE); kfree_skb(skb); return 0; } if(loghci) { A_PRINTF(">>> Send HCI %s packet len: %d\n", (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL", skb->len); if (type == HCI_COMMAND_TYPE) { A_PRINTF("HCI Command: OGF:0x%X OCF:0x%X \r\n", (HCI_GET_OP_CODE(skb->data)) >> 10, (HCI_GET_OP_CODE(skb->data)) & 0x3FF); } DebugDumpBytes(skb->data,skb->len,"BT HCI SEND Packet Dump"); }
/* * bt_send_frame - send data frames */ static int bt_send_frame(struct sk_buff *skb) { struct hci_dev *hdev = (struct hci_dev *)skb->dev; HCI_TRANSPORT_PACKET_TYPE type; AR6K_HCI_BRIDGE_INFO *pHcidevInfo; HTC_PACKET *pPacket; A_STATUS status = A_OK; struct sk_buff *txSkb = NULL; if (!hdev) { AR_DEBUG_PRINTF(ATH_DEBUG_WARN, ("HCI Bridge: bt_send_frame - no device\n")); return -ENODEV; } if (!test_bit(HCI_RUNNING, &hdev->flags)) { AR_DEBUG_PRINTF(ATH_DEBUG_TRC, ("HCI Bridge: bt_send_frame - not open\n")); return -EBUSY; } pHcidevInfo = (AR6K_HCI_BRIDGE_INFO *)hdev->driver_data; A_ASSERT(pHcidevInfo != NULL); AR_DEBUG_PRINTF(ATH_DEBUG_HCI_SEND, ("+bt_send_frame type: %d \n",bt_cb(skb)->pkt_type)); type = HCI_COMMAND_TYPE; switch (bt_cb(skb)->pkt_type) { case HCI_COMMAND_PKT: type = HCI_COMMAND_TYPE; hdev->stat.cmd_tx++; break; case HCI_ACLDATA_PKT: type = HCI_ACL_TYPE; hdev->stat.acl_tx++; break; case HCI_SCODATA_PKT: /* we don't support SCO over the bridge */ kfree_skb(skb); return 0; default: A_ASSERT(FALSE); kfree_skb(skb); return 0; } if (AR_DEBUG_LVL_CHECK(ATH_DEBUG_HCI_DUMP)) { AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(">>> Send HCI %s packet len: %d\n", (type == HCI_COMMAND_TYPE) ? "COMMAND" : "ACL", skb->len)); if (type == HCI_COMMAND_TYPE) { A_UINT16 opcode = HCI_GET_OP_CODE(skb->data); AR_DEBUG_PRINTF(ATH_DEBUG_ANY,(" HCI Command: OGF:0x%X OCF:0x%X \r\n", opcode >> 10, opcode & 0x3FF)); } AR_DEBUG_PRINTBUF(skb->data,skb->len,"BT HCI SEND Packet Dump"); }
ATHBT_STATE_INDICATION FCore_FilterBTCommand(BT_FILTER_CORE_INFO *pCore, A_UINT8 *pBuffer, int Length, ATHBT_STATE *pNewState) { ATHBT_STATE_INDICATION indication = ATH_BT_NOOP; ATHBT_STATE state = STATE_OFF; A_UINT16 command; if (!IS_LINK_CONTROL_CMD(pBuffer)) { /* we only filter link control commands */ return indication; } command = HCI_GET_OP_CODE(pBuffer); switch (command) { case HCI_INQUIRY : if (IS_STATE_FILTER_IGNORED(pCore, ATH_BT_INQUIRY)) { break; } indication = ATH_BT_INQUIRY; state = STATE_ON; break; case HCI_INQUIRY_CANCEL : if (IS_STATE_FILTER_IGNORED(pCore, ATH_BT_INQUIRY)) { break; } indication = ATH_BT_INQUIRY; state = STATE_OFF; break; case HCI_CREATE_CONNECTION : if (IS_STATE_FILTER_IGNORED(pCore, ATH_BT_CONNECT)) { break; } indication = ATH_BT_CONNECT; state = STATE_ON; break; case HCI_ACCEPT_CONN_REQ : if (IS_STATE_FILTER_IGNORED(pCore, ATH_BT_CONNECT)) { break; } indication = ATH_BT_CONNECT; state = STATE_ON; break; case HCI_ADD_SCO : /* we do not need to handle this command, we can pick up the connection complete event */ case HCI_DISCONNECT : /* we don't need to handle this command as we can pick up the disconnect event */ case HCI_PER_INQUIRY : case HCI_PER_INQUIRY_CANCEL : /* we do not handle these currently */ default : break; } if (indication != ATH_BT_NOOP) { /* the HCI filter simply determines the "precise" state and calls the shared function */ return FCore_FilterIndicatePreciseState(pCore, indication, state, pNewState); } return ATH_BT_NOOP; }