sfc: Use netif_set_real_num_{rx,tx}_queues()
[pandora-kernel.git] / drivers / net / sfc / nic.c
index be4d552..394dd92 100644 (file)
@@ -104,7 +104,7 @@ static inline void efx_write_buf_tbl(struct efx_nic *efx, efx_qword_t *value,
 static inline efx_qword_t *efx_event(struct efx_channel *channel,
                                     unsigned int index)
 {
-       return (((efx_qword_t *) (channel->eventq.addr)) + index);
+       return ((efx_qword_t *) (channel->eventq.addr)) + index;
 }
 
 /* See if an event is present
@@ -119,8 +119,8 @@ static inline efx_qword_t *efx_event(struct efx_channel *channel,
  */
 static inline int efx_event_present(efx_qword_t *event)
 {
-       return (!(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
-                 EFX_DWORD_IS_ALL_ONES(event->dword[1])));
+       return !(EFX_DWORD_IS_ALL_ONES(event->dword[0]) |
+                 EFX_DWORD_IS_ALL_ONES(event->dword[1]));
 }
 
 static bool efx_masked_compare_oword(const efx_oword_t *a, const efx_oword_t *b,
@@ -347,7 +347,7 @@ void efx_nic_free_buffer(struct efx_nic *efx, struct efx_buffer *buffer)
 static inline efx_qword_t *
 efx_tx_desc(struct efx_tx_queue *tx_queue, unsigned int index)
 {
-       return (((efx_qword_t *) (tx_queue->txd.addr)) + index);
+       return ((efx_qword_t *) (tx_queue->txd.addr)) + index;
 }
 
 /* This writes to the TX_DESC_WPTR; write pointer for TX descriptor ring */
@@ -356,7 +356,7 @@ static inline void efx_notify_tx_desc(struct efx_tx_queue *tx_queue)
        unsigned write_ptr;
        efx_dword_t reg;
 
-       write_ptr = tx_queue->write_count & EFX_TXQ_MASK;
+       write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
        EFX_POPULATE_DWORD_1(reg, FRF_AZ_TX_DESC_WPTR_DWORD, write_ptr);
        efx_writed_page(tx_queue->efx, &reg,
                        FR_AZ_TX_DESC_UPD_DWORD_P0, tx_queue->queue);
@@ -377,7 +377,7 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
        BUG_ON(tx_queue->write_count == tx_queue->insert_count);
 
        do {
-               write_ptr = tx_queue->write_count & EFX_TXQ_MASK;
+               write_ptr = tx_queue->write_count & tx_queue->ptr_mask;
                buffer = &tx_queue->buffer[write_ptr];
                txd = efx_tx_desc(tx_queue, write_ptr);
                ++tx_queue->write_count;
@@ -398,10 +398,11 @@ void efx_nic_push_buffers(struct efx_tx_queue *tx_queue)
 int efx_nic_probe_tx(struct efx_tx_queue *tx_queue)
 {
        struct efx_nic *efx = tx_queue->efx;
-       BUILD_BUG_ON(EFX_TXQ_SIZE < 512 || EFX_TXQ_SIZE > 4096 ||
-                    EFX_TXQ_SIZE & EFX_TXQ_MASK);
+       unsigned entries;
+
+       entries = tx_queue->ptr_mask + 1;
        return efx_alloc_special_buffer(efx, &tx_queue->txd,
-                                       EFX_TXQ_SIZE * sizeof(efx_qword_t));
+                                       entries * sizeof(efx_qword_t));
 }
 
 void efx_nic_init_tx(struct efx_tx_queue *tx_queue)
@@ -501,7 +502,7 @@ void efx_nic_remove_tx(struct efx_tx_queue *tx_queue)
 static inline efx_qword_t *
 efx_rx_desc(struct efx_rx_queue *rx_queue, unsigned int index)
 {
-       return (((efx_qword_t *) (rx_queue->rxd.addr)) + index);
+       return ((efx_qword_t *) (rx_queue->rxd.addr)) + index;
 }
 
 /* This creates an entry in the RX descriptor queue */
@@ -526,30 +527,32 @@ efx_build_rx_desc(struct efx_rx_queue *rx_queue, unsigned index)
  */
 void efx_nic_notify_rx_desc(struct efx_rx_queue *rx_queue)
 {
+       struct efx_nic *efx = rx_queue->efx;
        efx_dword_t reg;
        unsigned write_ptr;
 
        while (rx_queue->notified_count != rx_queue->added_count) {
-               efx_build_rx_desc(rx_queue,
-                                 rx_queue->notified_count &
-                                 EFX_RXQ_MASK);
+               efx_build_rx_desc(
+                       rx_queue,
+                       rx_queue->notified_count & rx_queue->ptr_mask);
                ++rx_queue->notified_count;
        }
 
        wmb();
-       write_ptr = rx_queue->added_count & EFX_RXQ_MASK;
+       write_ptr = rx_queue->added_count & rx_queue->ptr_mask;
        EFX_POPULATE_DWORD_1(reg, FRF_AZ_RX_DESC_WPTR_DWORD, write_ptr);
-       efx_writed_page(rx_queue->efx, &reg, FR_AZ_RX_DESC_UPD_DWORD_P0,
+       efx_writed_page(efx, &reg, FR_AZ_RX_DESC_UPD_DWORD_P0,
                        efx_rx_queue_index(rx_queue));
 }
 
 int efx_nic_probe_rx(struct efx_rx_queue *rx_queue)
 {
        struct efx_nic *efx = rx_queue->efx;
-       BUILD_BUG_ON(EFX_RXQ_SIZE < 512 || EFX_RXQ_SIZE > 4096 ||
-                    EFX_RXQ_SIZE & EFX_RXQ_MASK);
+       unsigned entries;
+
+       entries = rx_queue->ptr_mask + 1;
        return efx_alloc_special_buffer(efx, &rx_queue->rxd,
-                                       EFX_RXQ_SIZE * sizeof(efx_qword_t));
+                                       entries * sizeof(efx_qword_t));
 }
 
 void efx_nic_init_rx(struct efx_rx_queue *rx_queue)
@@ -682,15 +685,17 @@ efx_handle_tx_event(struct efx_channel *channel, efx_qword_t *event)
                /* Transmit completion */
                tx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_DESC_PTR);
                tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
-               tx_queue = &efx->tx_queue[tx_ev_q_label];
+               tx_queue = efx_channel_get_tx_queue(
+                       channel, tx_ev_q_label % EFX_TXQ_TYPES);
                tx_packets = ((tx_ev_desc_ptr - tx_queue->read_count) &
-                             EFX_TXQ_MASK);
+                             tx_queue->ptr_mask);
                channel->irq_mod_score += tx_packets;
                efx_xmit_done(tx_queue, tx_ev_desc_ptr);
        } else if (EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_WQ_FF_FULL)) {
                /* Rewrite the FIFO write pointer */
                tx_ev_q_label = EFX_QWORD_FIELD(*event, FSF_AZ_TX_EV_Q_LABEL);
-               tx_queue = &efx->tx_queue[tx_ev_q_label];
+               tx_queue = efx_channel_get_tx_queue(
+                       channel, tx_ev_q_label % EFX_TXQ_TYPES);
 
                if (efx_dev_registered(efx))
                        netif_tx_lock(efx->net_dev);
@@ -794,8 +799,8 @@ efx_handle_rx_bad_index(struct efx_rx_queue *rx_queue, unsigned index)
        struct efx_nic *efx = rx_queue->efx;
        unsigned expected, dropped;
 
-       expected = rx_queue->removed_count & EFX_RXQ_MASK;
-       dropped = (index - expected) & EFX_RXQ_MASK;
+       expected = rx_queue->removed_count & rx_queue->ptr_mask;
+       dropped = (index - expected) & rx_queue->ptr_mask;
        netif_info(efx, rx_err, efx->net_dev,
                   "dropped %d events (index=%d expected=%d)\n",
                   dropped, index, expected);
@@ -830,10 +835,10 @@ efx_handle_rx_event(struct efx_channel *channel, const efx_qword_t *event)
        WARN_ON(EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_Q_LABEL) !=
                channel->channel);
 
-       rx_queue = &efx->rx_queue[channel->channel];
+       rx_queue = efx_channel_get_rx_queue(channel);
 
        rx_ev_desc_ptr = EFX_QWORD_FIELD(*event, FSF_AZ_RX_EV_DESC_PTR);
-       expected_ptr = rx_queue->removed_count & EFX_RXQ_MASK;
+       expected_ptr = rx_queue->removed_count & rx_queue->ptr_mask;
        if (unlikely(rx_ev_desc_ptr != expected_ptr))
                efx_handle_rx_bad_index(rx_queue, rx_ev_desc_ptr);
 
@@ -882,7 +887,7 @@ efx_handle_generated_event(struct efx_channel *channel, efx_qword_t *event)
                /* The queue must be empty, so we won't receive any rx
                 * events, so efx_process_channel() won't refill the
                 * queue. Refill it here */
-               efx_fast_push_rx_descriptors(&efx->rx_queue[channel->channel]);
+               efx_fast_push_rx_descriptors(efx_channel_get_rx_queue(channel));
        else
                netif_dbg(efx, hw, efx->net_dev, "channel %d received "
                          "generated event "EFX_QWORD_FMT"\n",
@@ -1000,6 +1005,7 @@ efx_handle_driver_event(struct efx_channel *channel, efx_qword_t *event)
 
 int efx_nic_process_eventq(struct efx_channel *channel, int budget)
 {
+       struct efx_nic *efx = channel->efx;
        unsigned int read_ptr;
        efx_qword_t event, *p_event;
        int ev_code;
@@ -1024,7 +1030,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
                EFX_SET_QWORD(*p_event);
 
                /* Increment read pointer */
-               read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
+               read_ptr = (read_ptr + 1) & channel->eventq_mask;
 
                ev_code = EFX_QWORD_FIELD(event, FSF_AZ_EV_CODE);
 
@@ -1036,7 +1042,7 @@ int efx_nic_process_eventq(struct efx_channel *channel, int budget)
                        break;
                case FSE_AZ_EV_CODE_TX_EV:
                        tx_packets += efx_handle_tx_event(channel, &event);
-                       if (tx_packets >= EFX_TXQ_SIZE) {
+                       if (tx_packets > efx->txq_entries) {
                                spent = budget;
                                goto out;
                        }
@@ -1071,10 +1077,11 @@ out:
 int efx_nic_probe_eventq(struct efx_channel *channel)
 {
        struct efx_nic *efx = channel->efx;
-       BUILD_BUG_ON(EFX_EVQ_SIZE < 512 || EFX_EVQ_SIZE > 32768 ||
-                    EFX_EVQ_SIZE & EFX_EVQ_MASK);
+       unsigned entries;
+
+       entries = channel->eventq_mask + 1;
        return efx_alloc_special_buffer(efx, &channel->eventq,
-                                       EFX_EVQ_SIZE * sizeof(efx_qword_t));
+                                       entries * sizeof(efx_qword_t));
 }
 
 void efx_nic_init_eventq(struct efx_channel *channel)
@@ -1166,11 +1173,11 @@ void efx_nic_generate_fill_event(struct efx_channel *channel)
 
 static void efx_poll_flush_events(struct efx_nic *efx)
 {
-       struct efx_channel *channel = &efx->channel[0];
+       struct efx_channel *channel = efx_get_channel(efx, 0);
        struct efx_tx_queue *tx_queue;
        struct efx_rx_queue *rx_queue;
        unsigned int read_ptr = channel->eventq_read_ptr;
-       unsigned int end_ptr = (read_ptr - 1) & EFX_EVQ_MASK;
+       unsigned int end_ptr = (read_ptr - 1) & channel->eventq_mask;
 
        do {
                efx_qword_t *event = efx_event(channel, read_ptr);
@@ -1188,7 +1195,9 @@ static void efx_poll_flush_events(struct efx_nic *efx)
                        ev_queue = EFX_QWORD_FIELD(*event,
                                                   FSF_AZ_DRIVER_EV_SUBDATA);
                        if (ev_queue < EFX_TXQ_TYPES * efx->n_tx_channels) {
-                               tx_queue = efx->tx_queue + ev_queue;
+                               tx_queue = efx_get_tx_queue(
+                                       efx, ev_queue / EFX_TXQ_TYPES,
+                                       ev_queue % EFX_TXQ_TYPES);
                                tx_queue->flushed = FLUSH_DONE;
                        }
                } else if (ev_code == FSE_AZ_EV_CODE_DRIVER_EV &&
@@ -1198,7 +1207,7 @@ static void efx_poll_flush_events(struct efx_nic *efx)
                        ev_failed = EFX_QWORD_FIELD(
                                *event, FSF_AZ_DRIVER_EV_RX_FLUSH_FAIL);
                        if (ev_queue < efx->n_rx_channels) {
-                               rx_queue = efx->rx_queue + ev_queue;
+                               rx_queue = efx_get_rx_queue(efx, ev_queue);
                                rx_queue->flushed =
                                        ev_failed ? FLUSH_FAILED : FLUSH_DONE;
                        }
@@ -1208,7 +1217,7 @@ static void efx_poll_flush_events(struct efx_nic *efx)
                 * it's ok to throw away every non-flush event */
                EFX_SET_QWORD(*event);
 
-               read_ptr = (read_ptr + 1) & EFX_EVQ_MASK;
+               read_ptr = (read_ptr + 1) & channel->eventq_mask;
        } while (read_ptr != end_ptr);
 
        channel->eventq_read_ptr = read_ptr;
@@ -1219,6 +1228,7 @@ static void efx_poll_flush_events(struct efx_nic *efx)
  * serialise them */
 int efx_nic_flush_queues(struct efx_nic *efx)
 {
+       struct efx_channel *channel;
        struct efx_rx_queue *rx_queue;
        struct efx_tx_queue *tx_queue;
        int i, tx_pending, rx_pending;
@@ -1227,29 +1237,35 @@ int efx_nic_flush_queues(struct efx_nic *efx)
        efx->type->prepare_flush(efx);
 
        /* Flush all tx queues in parallel */
-       efx_for_each_tx_queue(tx_queue, efx)
-               efx_flush_tx_queue(tx_queue);
+       efx_for_each_channel(channel, efx) {
+               efx_for_each_channel_tx_queue(tx_queue, channel)
+                       efx_flush_tx_queue(tx_queue);
+       }
 
        /* The hardware supports four concurrent rx flushes, each of which may
         * need to be retried if there is an outstanding descriptor fetch */
        for (i = 0; i < EFX_FLUSH_POLL_COUNT; ++i) {
                rx_pending = tx_pending = 0;
-               efx_for_each_rx_queue(rx_queue, efx) {
-                       if (rx_queue->flushed == FLUSH_PENDING)
-                               ++rx_pending;
-               }
-               efx_for_each_rx_queue(rx_queue, efx) {
-                       if (rx_pending == EFX_RX_FLUSH_COUNT)
-                               break;
-                       if (rx_queue->flushed == FLUSH_FAILED ||
-                           rx_queue->flushed == FLUSH_NONE) {
-                               efx_flush_rx_queue(rx_queue);
-                               ++rx_pending;
+               efx_for_each_channel(channel, efx) {
+                       efx_for_each_channel_rx_queue(rx_queue, channel) {
+                               if (rx_queue->flushed == FLUSH_PENDING)
+                                       ++rx_pending;
                        }
                }
-               efx_for_each_tx_queue(tx_queue, efx) {
-                       if (tx_queue->flushed != FLUSH_DONE)
-                               ++tx_pending;
+               efx_for_each_channel(channel, efx) {
+                       efx_for_each_channel_rx_queue(rx_queue, channel) {
+                               if (rx_pending == EFX_RX_FLUSH_COUNT)
+                                       break;
+                               if (rx_queue->flushed == FLUSH_FAILED ||
+                                   rx_queue->flushed == FLUSH_NONE) {
+                                       efx_flush_rx_queue(rx_queue);
+                                       ++rx_pending;
+                               }
+                       }
+                       efx_for_each_channel_tx_queue(tx_queue, channel) {
+                               if (tx_queue->flushed != FLUSH_DONE)
+                                       ++tx_pending;
+                       }
                }
 
                if (rx_pending == 0 && tx_pending == 0)
@@ -1261,19 +1277,21 @@ int efx_nic_flush_queues(struct efx_nic *efx)
 
        /* Mark the queues as all flushed. We're going to return failure
         * leading to a reset, or fake up success anyway */
-       efx_for_each_tx_queue(tx_queue, efx) {
-               if (tx_queue->flushed != FLUSH_DONE)
-                       netif_err(efx, hw, efx->net_dev,
-                                 "tx queue %d flush command timed out\n",
-                                 tx_queue->queue);
-               tx_queue->flushed = FLUSH_DONE;
-       }
-       efx_for_each_rx_queue(rx_queue, efx) {
-               if (rx_queue->flushed != FLUSH_DONE)
-                       netif_err(efx, hw, efx->net_dev,
-                                 "rx queue %d flush command timed out\n",
-                                 efx_rx_queue_index(rx_queue));
-               rx_queue->flushed = FLUSH_DONE;
+       efx_for_each_channel(channel, efx) {
+               efx_for_each_channel_tx_queue(tx_queue, channel) {
+                       if (tx_queue->flushed != FLUSH_DONE)
+                               netif_err(efx, hw, efx->net_dev,
+                                         "tx queue %d flush command timed out\n",
+                                         tx_queue->queue);
+                       tx_queue->flushed = FLUSH_DONE;
+               }
+               efx_for_each_channel_rx_queue(rx_queue, channel) {
+                       if (rx_queue->flushed != FLUSH_DONE)
+                               netif_err(efx, hw, efx->net_dev,
+                                         "rx queue %d flush command timed out\n",
+                                         efx_rx_queue_index(rx_queue));
+                       rx_queue->flushed = FLUSH_DONE;
+               }
        }
 
        return -ETIMEDOUT;
@@ -1460,7 +1478,7 @@ static irqreturn_t efx_legacy_interrupt(int irq, void *dev_id)
  */
 static irqreturn_t efx_msi_interrupt(int irq, void *dev_id)
 {
-       struct efx_channel *channel = dev_id;
+       struct efx_channel *channel = *(struct efx_channel **)dev_id;
        struct efx_nic *efx = channel->efx;
        efx_oword_t *int_ker = efx->irq_status.addr;
        int syserr;
@@ -1535,7 +1553,8 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
        efx_for_each_channel(channel, efx) {
                rc = request_irq(channel->irq, efx_msi_interrupt,
                                 IRQF_PROBE_SHARED, /* Not shared */
-                                channel->name, channel);
+                                efx->channel_name[channel->channel],
+                                &efx->channel[channel->channel]);
                if (rc) {
                        netif_err(efx, drv, efx->net_dev,
                                  "failed to hook IRQ %d\n", channel->irq);
@@ -1547,7 +1566,7 @@ int efx_nic_init_interrupt(struct efx_nic *efx)
 
  fail2:
        efx_for_each_channel(channel, efx)
-               free_irq(channel->irq, channel);
+               free_irq(channel->irq, &efx->channel[channel->channel]);
  fail1:
        return rc;
 }
@@ -1560,7 +1579,7 @@ void efx_nic_fini_interrupt(struct efx_nic *efx)
        /* Disable MSI/MSI-X interrupts */
        efx_for_each_channel(channel, efx) {
                if (channel->irq)
-                       free_irq(channel->irq, channel);
+                       free_irq(channel->irq, &efx->channel[channel->channel]);
        }
 
        /* ACK legacy interrupt */
@@ -1830,8 +1849,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
        REGISTER_TABLE_BB_CZ(TX_DESC_PTR_TBL),
        REGISTER_TABLE_AA(EVQ_PTR_TBL_KER),
        REGISTER_TABLE_BB_CZ(EVQ_PTR_TBL),
-       /* The register buffer is allocated with slab, so we can't
-        * reasonably read all of the buffer table (up to 8MB!).
+       /* We can't reasonably read all of the buffer table (up to 8MB!).
         * However this driver will only use a few entries.  Reading
         * 1K entries allows for some expansion of queue count and
         * size before we need to change the version. */
@@ -1839,7 +1857,6 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
                                  A, A, 8, 1024),
        REGISTER_TABLE_DIMENSIONS(BUF_FULL_TBL, FR_BZ_BUF_FULL_TBL,
                                  B, Z, 8, 1024),
-       /* RX_FILTER_TBL{0,1} is huge and not used by this driver */
        REGISTER_TABLE_CZ(RX_MAC_FILTER_TBL0),
        REGISTER_TABLE_BB_CZ(TIMER_TBL),
        REGISTER_TABLE_BB_CZ(TX_PACE_TBL),
@@ -1849,6 +1866,7 @@ static const struct efx_nic_reg_table efx_nic_reg_tables[] = {
        REGISTER_TABLE_CZ(MC_TREG_SMEM),
        /* MSIX_PBA_TABLE is not mapped */
        /* SRM_DBG is not mapped (and is redundant with BUF_FLL_TBL) */
+       REGISTER_TABLE_BZ(RX_FILTER_TBL0),
 };
 
 size_t efx_nic_get_regs_len(struct efx_nic *efx)