/* We use the upper 4 bits for the PIO * controller ID and the lower 12 bits * for the packet index (in the cache).
*/ switch (queue->mmio_base) { case B43legacy_MMIO_PIO1_BASE: break; case B43legacy_MMIO_PIO2_BASE:
cookie = 0x1000; break; case B43legacy_MMIO_PIO3_BASE:
cookie = 0x2000; break; case B43legacy_MMIO_PIO4_BASE:
cookie = 0x3000; break; default:
B43legacy_WARN_ON(1);
}
packetindex = pio_txpacket_getindex(packet);
B43legacy_WARN_ON(!(((u16)packetindex & 0xF000) == 0x0000));
cookie |= (u16)packetindex;
octets = (u16)skb->len + sizeof(struct b43legacy_txhdr_fw3); if (queue->tx_devq_size < octets) {
b43legacywarn(queue->dev->wl, "PIO queue too small. " "Dropping packet.\n"); /* Drop it silently (return success) */
free_txpacket(packet, 1); return 0;
}
B43legacy_WARN_ON(queue->tx_devq_packets >
B43legacy_PIO_MAXTXDEVQPACKETS);
B43legacy_WARN_ON(queue->tx_devq_used > queue->tx_devq_size); /* Check if there is sufficient free space on the device * TX queue. If not, return and let the TX tasklet * retry later.
*/ if (queue->tx_devq_packets == B43legacy_PIO_MAXTXDEVQPACKETS) return -EBUSY; if (queue->tx_devq_used + octets > queue->tx_devq_size) return -EBUSY; /* Now poke the device. */
err = pio_tx_write_fragment(queue, skb, packet, sizeof(struct b43legacy_txhdr_fw3)); if (unlikely(err == -ENOKEY)) { /* Drop this packet, as we don't have the encryption key
* anymore and must not transmit it unencrypted. */
free_txpacket(packet, 1); return 0;
}
/* Account for the packet size. * (We must not overflow the device TX queue)
*/
queue->tx_devq_packets++;
queue->tx_devq_used += octets;
/* Transmission started, everything ok, move the * packet to the txrunning list.
*/
list_move_tail(&packet->list, &queue->txrunning);
spin_lock_irqsave(&dev->wl->irq_lock, flags); if (queue->tx_frozen) goto out_unlock;
txctl = b43legacy_pio_read(queue, B43legacy_PIO_TXCTL); if (txctl & B43legacy_PIO_TXCTL_SUSPEND) goto out_unlock;
list_for_each_entry_safe(packet, tmp_packet, &queue->txqueue, list) { /* Try to transmit the packet. This can fail, if * the device queue is full. In case of failure, the * packet is left in the txqueue. * If transmission succeed, the packet is moved to txrunning. * If it is impossible to transmit the packet, it * is dropped.
*/
err = pio_tx_packet(packet); if (err) break;
}
out_unlock:
spin_unlock_irqrestore(&dev->wl->irq_lock, flags);
}
staticvoid setup_txqueues(struct b43legacy_pioqueue *queue)
{ struct b43legacy_pio_txpacket *packet; int i;
queue->nr_txfree = B43legacy_PIO_MAXTXPACKETS; for (i = 0; i < B43legacy_PIO_MAXTXPACKETS; i++) {
packet = &(queue->tx_packets_cache[i]);
/* preserve the confiured retry limit before clearing the status * The xmit function has overwritten the rc's value with the actual
* retry limit done by the hardware */
retry_limit = info->status.rates[0].count;
ieee80211_tx_info_clear_status(info);
if (status->acked)
info->flags |= IEEE80211_TX_STAT_ACK;
if (status->rts_count > dev->wl->hw->conf.short_frame_max_tx_count) { /* * If the short retries (RTS, not data frame) have exceeded * the limit, the hw will not have tried the selected rate, * but will have used the fallback rate instead. * Don't let the rate control count attempts for the selected * rate in this case, otherwise the statistics will be off.
*/
info->status.rates[0].count = 0;
info->status.rates[1].count = status->frame_count;
} else { if (status->frame_count > retry_limit) {
info->status.rates[0].count = retry_limit;
info->status.rates[1].count = status->frame_count -
retry_limit;
free_txpacket(packet, 1); /* If there are packets on the txqueue, poke the tasklet * to transmit them.
*/ if (!list_empty(&queue->txqueue))
tasklet_schedule(&queue->txtask);
}
staticvoid pio_rx_error(struct b43legacy_pioqueue *queue, int clear_buffers, constchar *error)
{ int i;
b43legacyerr(queue->dev->wl, "PIO RX error: %s\n", error);
b43legacy_pio_write(queue, B43legacy_PIO_RXCTL,
B43legacy_PIO_RXCTL_READY); if (clear_buffers) {
B43legacy_WARN_ON(queue->mmio_base != B43legacy_MMIO_PIO1_BASE); for (i = 0; i < 15; i++) { /* Dummy read. */
b43legacy_pio_read(queue, B43legacy_PIO_RXDATA);
}
}
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.