Пример #1
0
static int wl1271_tx_send_packet(struct wl1271 *wl, struct sk_buff *skb,
				 struct ieee80211_tx_info *control)
{

	struct wl1271_tx_hw_descr *desc;
	int len;

	/* FIXME: This is a workaround for getting non-aligned packets.
	   This happens at least with EAPOL packets from the user space.
	   Our DMA requires packets to be aligned on a 4-byte boundary.
	*/
	if (unlikely((long)skb->data & 0x03)) {
		int offset = (4 - (long)skb->data) & 0x03;
		wl1271_debug(DEBUG_TX, "skb offset %d", offset);

		/* check whether the current skb can be used */
		if (!skb_cloned(skb) && (skb_tailroom(skb) >= offset)) {
			unsigned char *src = skb->data;

			/* align the buffer on a 4-byte boundary */
			skb_reserve(skb, offset);
			memmove(skb->data, src, skb->len);
		} else {
			wl1271_info("No handler, fixme!");
			return -EINVAL;
		}
	}

	len = WL1271_TX_ALIGN(skb->len);

	/* perform a fixed address block write with the packet */
	wl1271_spi_reg_write(wl, WL1271_SLV_MEM_DATA, skb->data, len, true);

	/* write packet new counter into the write access register */
	wl->tx_packets_count++;
	wl1271_reg_write32(wl, WL1271_HOST_WR_ACCESS, wl->tx_packets_count);

	desc = (struct wl1271_tx_hw_descr *) skb->data;
	wl1271_debug(DEBUG_TX, "tx id %u skb 0x%p payload %u (%u words)",
		     desc->id, skb, len, desc->length);

	return 0;
}
Пример #2
0
void wl1271_rx(struct wl1271 *wl, struct wl1271_fw_status *status)
{
	struct wl1271_acx_mem_map *wl_mem_map = wl->target_mem_map;
	u32 buf_size;
	u32 fw_rx_counter  = status->fw_rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
	u32 drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
	u32 mem_block;

	while (drv_rx_counter != fw_rx_counter) {
		mem_block = wl1271_rx_get_mem_block(status, drv_rx_counter);
		buf_size = wl1271_rx_get_buf_size(status, drv_rx_counter);

		if (buf_size == 0) {
			wl1271_warning("received empty data");
			break;
		}

		wl->rx_mem_pool_addr.addr =
			(mem_block << 8) + wl_mem_map->packet_memory_pool_start;
		wl->rx_mem_pool_addr.addr_extra =
			wl->rx_mem_pool_addr.addr + 4;

		/* Choose the block we want to read */
		wl1271_spi_reg_write(wl, WL1271_SLV_REG_DATA,
				     &wl->rx_mem_pool_addr,
				     sizeof(wl->rx_mem_pool_addr), false);

		wl1271_rx_handle_data(wl, buf_size);

		wl->rx_counter++;
		drv_rx_counter = wl->rx_counter & NUM_RX_PKT_DESC_MOD_MASK;
	}

	wl1271_reg_write32(wl, RX_DRIVER_COUNTER_ADDRESS, wl->rx_counter);

	/* This is a workaround for some problems in the chip */
	wl1271_reg_write32(wl, RX_DRIVER_DUMMY_WRITE_ADDRESS, 0x1);

}