Example #1
0
static void hci_h4p_rx_tasklet(unsigned long data)
{
	u8 byte;
	struct hci_h4p_info *info = (struct hci_h4p_info *)data;

	NBT_DBG("tasklet woke up\n");
	NBT_DBG_TRANSFER("rx_tasklet woke up\ndata ");

	while (hci_h4p_inb(info, UART_LSR) & UART_LSR_DR) {
		byte = hci_h4p_inb(info, UART_RX);
		if (info->garbage_bytes) {
			info->garbage_bytes--;
			continue;
		}
		if (info->rx_skb == NULL) {
			info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE,
						    GFP_ATOMIC | GFP_DMA);
			if (!info->rx_skb) {
				dev_err(info->dev,
					"No memory for new packet\n");
				goto finish_rx;
			}
			info->rx_state = WAIT_FOR_PKT_TYPE;
			info->rx_skb->dev = (void *)info->hdev;
		}
		info->hdev->stat.byte_rx++;
		NBT_DBG_TRANSFER_NF("0x%.2x  ", byte);
		hci_h4p_handle_byte(info, byte);
	}

	if (!info->rx_enabled) {
		if (hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT &&
						  info->autorts) {
			__hci_h4p_set_auto_ctsrts(info, 0 , UART_EFR_RTS);
			info->autorts = 0;
		}
		/* Flush posted write to avoid spurious interrupts */
		hci_h4p_inb(info, UART_OMAP_SCR);
		hci_h4p_set_clk(info, &info->rx_clocks_en, 0);
	}

finish_rx:
	NBT_DBG_TRANSFER_NF("\n");
	NBT_DBG("rx_ended\n");
}
Example #2
0
static void brf6150_tx_tasklet(unsigned long data)
{
	unsigned int sent = 0;
	unsigned long flags;
	struct sk_buff *skb;
	struct brf6150_info *info = (struct brf6150_info *)data;

	NBT_DBG_TRANSFER("tx_tasklet woke up\n data ");

	skb = skb_dequeue(&info->txq);
	if (!skb) {
		/* No data in buffer */
		brf6150_enable_pm_tx(info);
		return;
	}

	/* Copy data to tx fifo */
	while (!(brf6150_inb(info, UART_OMAP_SSR) & UART_OMAP_SSR_TXFULL) &&
	       (sent < skb->len)) {
		NBT_DBG_TRANSFER_NF("0x%.2x ", skb->data[sent]);
		brf6150_outb(info, UART_TX, skb->data[sent]);
		sent++;
	}

	info->hdev->stat.byte_tx += sent;
	NBT_DBG_TRANSFER_NF("\n");
	if (skb->len == sent) {
		kfree_skb(skb);
		clk_disable(info->uart_ck);
	} else {
		skb_pull(skb, sent);
		skb_queue_head(&info->txq, skb);
	}

	spin_lock_irqsave(&info->lock, flags);
	brf6150_outb(info, UART_IER, brf6150_inb(info, UART_IER) | UART_IER_THRI);
	spin_unlock_irqrestore(&info->lock, flags);
}
Example #3
0
static void hci_h4p_tx_tasklet(unsigned long data)
{
	unsigned int sent = 0;
	struct sk_buff *skb;
	struct hci_h4p_info *info = (struct hci_h4p_info *)data;

	NBT_DBG("tasklet woke up\n");
	NBT_DBG_TRANSFER("tx_tasklet woke up\n data ");

	if (info->autorts != info->rx_enabled) {
		if (hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT) {
			if (info->autorts && !info->rx_enabled) {
				__hci_h4p_set_auto_ctsrts(info, 0,
							  UART_EFR_RTS);
				info->autorts = 0;
			}
			if (!info->autorts && info->rx_enabled) {
				__hci_h4p_set_auto_ctsrts(info, 1,
							  UART_EFR_RTS);
				info->autorts = 1;
			}
		} else {
			hci_h4p_outb(info, UART_OMAP_SCR,
				     hci_h4p_inb(info, UART_OMAP_SCR) |
				     UART_OMAP_SCR_EMPTY_THR);
			goto finish_tx;
		}
	}

	skb = skb_dequeue(&info->txq);
	if (!skb) {
		/* No data in buffer */
		NBT_DBG("skb ready\n");
		if (hci_h4p_inb(info, UART_LSR) & UART_LSR_TEMT) {
			hci_h4p_outb(info, UART_IER,
				     hci_h4p_inb(info, UART_IER) &
				     ~UART_IER_THRI);
			hci_h4p_inb(info, UART_OMAP_SCR);
			hci_h4p_disable_tx(info);
			return;
		} else
			hci_h4p_outb(info, UART_OMAP_SCR,
				     hci_h4p_inb(info, UART_OMAP_SCR) |
				     UART_OMAP_SCR_EMPTY_THR);
		goto finish_tx;
	}

	/* Copy data to tx fifo */
	while (!(hci_h4p_inb(info, UART_OMAP_SSR) & UART_OMAP_SSR_TXFULL) &&
	       (sent < skb->len)) {
		NBT_DBG_TRANSFER_NF("0x%.2x ", skb->data[sent]);
		hci_h4p_outb(info, UART_TX, skb->data[sent]);
		sent++;
	}

	info->hdev->stat.byte_tx += sent;
	NBT_DBG_TRANSFER_NF("\n");
	if (skb->len == sent) {
		kfree_skb(skb);
	} else {
		skb_pull(skb, sent);
		skb_queue_head(&info->txq, skb);
	}

	hci_h4p_outb(info, UART_OMAP_SCR, hci_h4p_inb(info, UART_OMAP_SCR) &
						     ~UART_OMAP_SCR_EMPTY_THR);
	hci_h4p_outb(info, UART_IER, hci_h4p_inb(info, UART_IER) |
						 UART_IER_THRI);

finish_tx:
	/* Flush posted write to avoid spurious interrupts */
	hci_h4p_inb(info, UART_OMAP_SCR);

}
Example #4
0
static inline void brf6150_rx(struct brf6150_info *info)
{
	u8 byte;

	NBT_DBG_TRANSFER("rx_tasklet woke up\ndata ");

	while (brf6150_inb(info, UART_LSR) & UART_LSR_DR) {
		if (info->rx_skb == NULL) {
			info->rx_skb = bt_skb_alloc(HCI_MAX_FRAME_SIZE, GFP_ATOMIC);
			if (!info->rx_skb) {
				printk(KERN_WARNING "brf6150: Can't allocate memory for new packet\n");
				return;
			}
			info->rx_state = WAIT_FOR_PKT_TYPE;
			info->rx_skb->dev = (void *)info->hdev;
			brf6150_disable_pm_rx(info);
			clk_enable(info->uart_ck);
		}

		byte = brf6150_inb(info, UART_RX);
		if (info->garbage_bytes) {
			info->garbage_bytes--;
			info->hdev->stat.err_rx++;
			continue;
		}
		info->hdev->stat.byte_rx++;
		NBT_DBG_TRANSFER_NF("0x%.2x  ", byte);
		switch (info->rx_state) {
		case WAIT_FOR_PKT_TYPE:
			bt_cb(info->rx_skb)->pkt_type = byte;
			info->rx_count = brf6150_get_hdr_len(byte);
			if (info->rx_count >= 0) {
				info->rx_state = WAIT_FOR_HEADER;
			} else {
				info->hdev->stat.err_rx++;
				kfree_skb(info->rx_skb);
				info->rx_skb = NULL;
				clk_disable(info->uart_ck);
			}
			break;
		case WAIT_FOR_HEADER:
			info->rx_count--;
			*skb_put(info->rx_skb, 1) = byte;
			if (info->rx_count == 0) {
				info->rx_count = brf6150_get_data_len(info, info->rx_skb);
				if (info->rx_count > skb_tailroom(info->rx_skb)) {
					printk(KERN_WARNING "brf6150: Frame is %ld bytes too long.\n",
					       info->rx_count - skb_tailroom(info->rx_skb));
					info->rx_skb = NULL;
					info->garbage_bytes = info->rx_count - skb_tailroom(info->rx_skb);
					clk_disable(info->uart_ck);
					break;
				}
				info->rx_state = WAIT_FOR_DATA;
				if (bt_cb(info->rx_skb)->pkt_type == H4_NEG_PKT) {
					brf6150_negotiation_packet(info, info->rx_skb);
					info->rx_skb = NULL;
					clk_disable(info->uart_ck);
					return;
				}
				if (bt_cb(info->rx_skb)->pkt_type == H4_ALIVE_PKT) {
					brf6150_alive_packet(info, info->rx_skb);
					info->rx_skb = NULL;
					clk_disable(info->uart_ck);
					return;
				}
			}
			break;
		case WAIT_FOR_DATA:
			info->rx_count--;
			*skb_put(info->rx_skb, 1) = byte;
			if (info->rx_count == 0) {
				brf6150_recv_frame(info, info->rx_skb);
				info->rx_skb = NULL;
				clk_disable(info->uart_ck);
			}
			break;
		default:
			WARN_ON(1);
			break;
		}
	}

	NBT_DBG_TRANSFER_NF("\n");
}