Make desc_info structure specific to the queue type, which
allows us to cut down the Rx and AdminQ descriptor sizes by
not including all the fields needed for the Tx desriptors.
Before:
struct ionic_desc_info {
/* size: 464, cachelines: 8, members: 6 */
After:
struct ionic_tx_desc_info {
/* size: 464, cachelines: 8, members: 6 */
struct ionic_rx_desc_info {
/* size: 224, cachelines: 4, members: 2 */
struct ionic_admin_desc_info {
/* size: 8, cachelines: 1, members: 1 */
Suggested-by: Neel Patel <npatel2@amd.com>
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
Signed-off-by: Shannon Nelson <shannon.nelson@amd.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
-void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, void *arg)
+void ionic_q_post(struct ionic_queue *q, bool ring_doorbell)
- struct ionic_desc_info *desc_info;
struct ionic_lif *lif = q->lif;
struct device *dev = q->dev;
struct ionic_lif *lif = q->lif;
struct device *dev = q->dev;
- desc_info = &q->info[q->head_idx];
- desc_info->arg = arg;
-
q->head_idx = (q->head_idx + 1) & (q->num_descs - 1);
dev_dbg(dev, "lif=%d qname=%s qid=%d qtype=%d p_index=%d ringdb=%d\n",
q->head_idx = (q->head_idx + 1) & (q->num_descs - 1);
dev_dbg(dev, "lif=%d qname=%s qid=%d qtype=%d p_index=%d ringdb=%d\n",
struct ionic_queue;
struct ionic_qcq;
struct ionic_queue;
struct ionic_qcq;
#define IONIC_MAX_BUF_LEN ((u16)-1)
#define IONIC_PAGE_SIZE PAGE_SIZE
#define IONIC_MAX_BUF_LEN ((u16)-1)
#define IONIC_PAGE_SIZE PAGE_SIZE
-#define IONIC_MAX_FRAGS (1 + IONIC_TX_MAX_SG_ELEMS_V1)
+#define IONIC_TX_MAX_FRAGS (1 + IONIC_TX_MAX_SG_ELEMS_V1)
+#define IONIC_RX_MAX_FRAGS (1 + IONIC_RX_MAX_SG_ELEMS)
-struct ionic_desc_info {
+struct ionic_tx_desc_info {
unsigned int bytes;
unsigned int nbufs;
unsigned int bytes;
unsigned int nbufs;
struct xdp_frame *xdpf;
enum xdp_action act;
struct ionic_buf_info bufs[MAX_SKB_FRAGS + 1];
};
struct xdp_frame *xdpf;
enum xdp_action act;
struct ionic_buf_info bufs[MAX_SKB_FRAGS + 1];
};
+struct ionic_rx_desc_info {
+ unsigned int nbufs;
+ struct ionic_buf_info bufs[IONIC_RX_MAX_FRAGS];
+};
+
+struct ionic_admin_desc_info {
+ void *ctx;
+};
+
#define IONIC_QUEUE_NAME_MAX_SZ 16
struct ionic_queue {
struct device *dev;
struct ionic_lif *lif;
#define IONIC_QUEUE_NAME_MAX_SZ 16
struct ionic_queue {
struct device *dev;
struct ionic_lif *lif;
- struct ionic_desc_info *info;
+ union {
+ void *info;
+ struct ionic_tx_desc_info *tx_info;
+ struct ionic_rx_desc_info *rx_info;
+ struct ionic_admin_desc_info *admin_info;
+ };
u64 dbval;
unsigned long dbell_deadline;
unsigned long dbell_jiffies;
u64 dbval;
unsigned long dbell_deadline;
unsigned long dbell_jiffies;
struct ionic_queue *q, unsigned int index, const char *name,
unsigned int num_descs, size_t desc_size,
size_t sg_desc_size, unsigned int pid);
struct ionic_queue *q, unsigned int index, const char *name,
unsigned int num_descs, size_t desc_size,
size_t sg_desc_size, unsigned int pid);
-void ionic_q_post(struct ionic_queue *q, bool ring_doorbell, void *arg);
+void ionic_q_post(struct ionic_queue *q, bool ring_doorbell);
bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos);
int ionic_heartbeat_check(struct ionic *ionic);
bool ionic_q_is_posted(struct ionic_queue *q, unsigned int pos);
int ionic_heartbeat_check(struct ionic *ionic);
unsigned int num_descs, unsigned int desc_size,
unsigned int cq_desc_size,
unsigned int sg_desc_size,
unsigned int num_descs, unsigned int desc_size,
unsigned int cq_desc_size,
unsigned int sg_desc_size,
+ unsigned int desc_info_size,
unsigned int pid, struct ionic_qcq **qcq)
{
struct ionic_dev *idev = &lif->ionic->idev;
unsigned int pid, struct ionic_qcq **qcq)
{
struct ionic_dev *idev = &lif->ionic->idev;
new->q.dev = dev;
new->flags = flags;
new->q.dev = dev;
new->flags = flags;
- new->q.info = vcalloc(num_descs, sizeof(*new->q.info));
+ new->q.info = vcalloc(num_descs, desc_info_size);
if (!new->q.info) {
netdev_err(lif->netdev, "Cannot allocate queue info\n");
err = -ENOMEM;
if (!new->q.info) {
netdev_err(lif->netdev, "Cannot allocate queue info\n");
err = -ENOMEM;
IONIC_ADMINQ_LENGTH,
sizeof(struct ionic_admin_cmd),
sizeof(struct ionic_admin_comp),
IONIC_ADMINQ_LENGTH,
sizeof(struct ionic_admin_cmd),
sizeof(struct ionic_admin_comp),
- 0, lif->kern_pid, &lif->adminqcq);
+ 0,
+ sizeof(struct ionic_admin_desc_info),
+ lif->kern_pid, &lif->adminqcq);
if (err)
return err;
ionic_debugfs_add_qcq(lif, lif->adminqcq);
if (err)
return err;
ionic_debugfs_add_qcq(lif, lif->adminqcq);
flags, IONIC_NOTIFYQ_LENGTH,
sizeof(struct ionic_notifyq_cmd),
sizeof(union ionic_notifyq_comp),
flags, IONIC_NOTIFYQ_LENGTH,
sizeof(struct ionic_notifyq_cmd),
sizeof(union ionic_notifyq_comp),
- 0, lif->kern_pid, &lif->notifyqcq);
+ 0,
+ sizeof(struct ionic_admin_desc_info),
+ lif->kern_pid, &lif->notifyqcq);
if (err)
goto err_out;
ionic_debugfs_add_qcq(lif, lif->notifyqcq);
if (err)
goto err_out;
ionic_debugfs_add_qcq(lif, lif->notifyqcq);
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, txq_i, "hwstamp_tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, txq_i, "hwstamp_tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
+ sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &txq);
if (err)
goto err_qcq_alloc;
lif->kern_pid, &txq);
if (err)
goto err_qcq_alloc;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, rxq_i, "hwstamp_rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, rxq_i, "hwstamp_rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
+ sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &rxq);
if (err)
goto err_qcq_alloc;
lif->kern_pid, &rxq);
if (err)
goto err_qcq_alloc;
for (i = 0; i < lif->nxqs; i++) {
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
for (i = 0; i < lif->nxqs; i++) {
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
+ sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &lif->txqcqs[i]);
if (err)
goto err_out;
lif->kern_pid, &lif->txqcqs[i]);
if (err)
goto err_out;
for (i = 0; i < lif->nxqs; i++) {
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
for (i = 0; i < lif->nxqs; i++) {
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
+ sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &lif->rxqcqs[i]);
if (err)
goto err_out;
lif->kern_pid, &lif->rxqcqs[i]);
if (err)
goto err_out;
flags = IONIC_QCQ_F_TX_STATS | IONIC_QCQ_F_SG;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
4, desc_sz, comp_sz, sg_desc_sz,
flags = IONIC_QCQ_F_TX_STATS | IONIC_QCQ_F_SG;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
4, desc_sz, comp_sz, sg_desc_sz,
+ sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &lif->txqcqs[i]);
if (err)
goto err_out;
lif->kern_pid, &lif->txqcqs[i]);
if (err)
goto err_out;
flags = lif->txqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
flags = lif->txqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_TXQ, i, "tx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
+ sizeof(struct ionic_tx_desc_info),
lif->kern_pid, &tx_qcqs[i]);
if (err)
goto err_out;
lif->kern_pid, &tx_qcqs[i]);
if (err)
goto err_out;
flags = IONIC_QCQ_F_RX_STATS | IONIC_QCQ_F_SG;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
4, desc_sz, comp_sz, sg_desc_sz,
flags = IONIC_QCQ_F_RX_STATS | IONIC_QCQ_F_SG;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
4, desc_sz, comp_sz, sg_desc_sz,
+ sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &lif->rxqcqs[i]);
if (err)
goto err_out;
lif->kern_pid, &lif->rxqcqs[i]);
if (err)
goto err_out;
flags = lif->rxqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
flags = lif->rxqcqs[i]->flags & ~IONIC_QCQ_F_INTR;
err = ionic_qcq_alloc(lif, IONIC_QTYPE_RXQ, i, "rx", flags,
num_desc, desc_sz, comp_sz, sg_desc_sz,
+ sizeof(struct ionic_rx_desc_info),
lif->kern_pid, &rx_qcqs[i]);
if (err)
goto err_out;
lif->kern_pid, &rx_qcqs[i]);
if (err)
goto err_out;
dev_dbg(dev, "notifyq->hw_index %d\n", q->hw_index);
/* preset the callback info */
dev_dbg(dev, "notifyq->hw_index %d\n", q->hw_index);
/* preset the callback info */
+ q->admin_info[0].ctx = lif;
qcq->flags |= IONIC_QCQ_F_INITED;
qcq->flags |= IONIC_QCQ_F_INITED;
union ionic_q_identity __iomem *q_ident;
struct ionic *ionic = lif->ionic;
struct ionic_dev *idev;
union ionic_q_identity __iomem *q_ident;
struct ionic *ionic = lif->ionic;
struct ionic_dev *idev;
dev_dbg(ionic->dev, " qtype[%d].sg_desc_stride = %d\n",
qtype, qti->sg_desc_stride);
dev_dbg(ionic->dev, " qtype[%d].sg_desc_stride = %d\n",
qtype, qti->sg_desc_stride);
- if (qti->max_sg_elems >= IONIC_MAX_FRAGS) {
- qti->max_sg_elems = IONIC_MAX_FRAGS - 1;
- dev_dbg(ionic->dev, "limiting qtype %d max_sg_elems to IONIC_MAX_FRAGS-1 %d\n",
- qtype, qti->max_sg_elems);
- }
+ if (qtype == IONIC_QTYPE_TXQ)
+ max_frags = IONIC_TX_MAX_FRAGS;
+ else if (qtype == IONIC_QTYPE_RXQ)
+ max_frags = IONIC_RX_MAX_FRAGS;
+ else
+ max_frags = 1;
- if (qti->max_sg_elems > MAX_SKB_FRAGS) {
- qti->max_sg_elems = MAX_SKB_FRAGS;
- dev_dbg(ionic->dev, "limiting qtype %d max_sg_elems to MAX_SKB_FRAGS %d\n",
- qtype, qti->max_sg_elems);
- }
+ qti->max_sg_elems = min_t(u16, max_frags - 1, MAX_SKB_FRAGS);
+ dev_dbg(ionic->dev, "qtype %d max_sg_elems %d\n",
+ qtype, qti->max_sg_elems);
static void ionic_adminq_flush(struct ionic_lif *lif)
{
static void ionic_adminq_flush(struct ionic_lif *lif)
{
- struct ionic_desc_info *desc_info;
+ struct ionic_admin_desc_info *desc_info;
struct ionic_admin_cmd *desc;
unsigned long irqflags;
struct ionic_queue *q;
struct ionic_admin_cmd *desc;
unsigned long irqflags;
struct ionic_queue *q;
while (q->tail_idx != q->head_idx) {
desc = &q->adminq[q->tail_idx];
while (q->tail_idx != q->head_idx) {
desc = &q->adminq[q->tail_idx];
- desc_info = &q->info[q->tail_idx];
+ desc_info = &q->admin_info[q->tail_idx];
memset(desc, 0, sizeof(union ionic_adminq_cmd));
memset(desc, 0, sizeof(union ionic_adminq_cmd));
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
}
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
}
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
}
static void ionic_adminq_clean(struct ionic_queue *q,
}
static void ionic_adminq_clean(struct ionic_queue *q,
- struct ionic_desc_info *desc_info,
+ struct ionic_admin_desc_info *desc_info,
struct ionic_admin_comp *comp)
{
struct ionic_admin_comp *comp)
{
- struct ionic_admin_ctx *ctx = desc_info->arg;
+ struct ionic_admin_ctx *ctx = desc_info->ctx;
comp = &((union ionic_notifyq_comp *)cq->base)[cq->tail_idx];
q = cq->bound_q;
comp = &((union ionic_notifyq_comp *)cq->base)[cq->tail_idx];
q = cq->bound_q;
+ lif = q->admin_info[0].ctx;
netdev = lif->netdev;
eid = le64_to_cpu(comp->event.eid);
netdev = lif->netdev;
eid = le64_to_cpu(comp->event.eid);
bool ionic_adminq_service(struct ionic_cq *cq)
{
bool ionic_adminq_service(struct ionic_cq *cq)
{
+ struct ionic_admin_desc_info *desc_info;
struct ionic_queue *q = cq->bound_q;
struct ionic_queue *q = cq->bound_q;
- struct ionic_desc_info *desc_info;
struct ionic_admin_comp *comp;
u16 index;
struct ionic_admin_comp *comp;
u16 index;
- desc_info = &q->info[q->tail_idx];
+ desc_info = &q->admin_info[q->tail_idx];
index = q->tail_idx;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
index = q->tail_idx;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
- if (likely(desc_info->arg))
+ if (likely(desc_info->ctx))
ionic_adminq_clean(q, desc_info, comp);
ionic_adminq_clean(q, desc_info, comp);
} while (index != le16_to_cpu(comp->comp_index));
return true;
} while (index != le16_to_cpu(comp->comp_index));
return true;
int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
{
int ionic_adminq_post(struct ionic_lif *lif, struct ionic_admin_ctx *ctx)
{
+ struct ionic_admin_desc_info *desc_info;
struct ionic_admin_cmd *desc;
unsigned long irqflags;
struct ionic_queue *q;
struct ionic_admin_cmd *desc;
unsigned long irqflags;
struct ionic_queue *q;
+ desc_info = &q->admin_info[q->head_idx];
+ desc_info->ctx = ctx;
+
desc = &q->adminq[q->head_idx];
memcpy(desc, &ctx->cmd, sizeof(ctx->cmd));
desc = &q->adminq[q->head_idx];
memcpy(desc, &ctx->cmd, sizeof(ctx->cmd));
dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
&ctx->cmd, sizeof(ctx->cmd), true);
dynamic_hex_dump("cmd ", DUMP_PREFIX_OFFSET, 16, 1,
&ctx->cmd, sizeof(ctx->cmd), true);
- ionic_q_post(q, true, ctx);
err_out:
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
err_out:
spin_unlock_irqrestore(&lif->adminq_lock, irqflags);
size_t offset, size_t len);
static void ionic_tx_desc_unmap_bufs(struct ionic_queue *q,
size_t offset, size_t len);
static void ionic_tx_desc_unmap_bufs(struct ionic_queue *q,
- struct ionic_desc_info *desc_info);
+ struct ionic_tx_desc_info *desc_info);
static void ionic_tx_clean(struct ionic_queue *q,
static void ionic_tx_clean(struct ionic_queue *q,
- struct ionic_desc_info *desc_info,
+ struct ionic_tx_desc_info *desc_info,
struct ionic_txq_comp *comp);
struct ionic_txq_comp *comp);
-static inline void ionic_txq_post(struct ionic_queue *q, bool ring_dbell,
- void *arg)
+static inline void ionic_txq_post(struct ionic_queue *q, bool ring_dbell)
- ionic_q_post(q, ring_dbell, arg);
+ ionic_q_post(q, ring_dbell);
-static inline void ionic_rxq_post(struct ionic_queue *q, bool ring_dbell,
- void *arg)
+static inline void ionic_rxq_post(struct ionic_queue *q, bool ring_dbell)
- ionic_q_post(q, ring_dbell, arg);
+ ionic_q_post(q, ring_dbell);
}
bool ionic_txq_poke_doorbell(struct ionic_queue *q)
}
bool ionic_txq_poke_doorbell(struct ionic_queue *q)
static struct sk_buff *ionic_rx_frags(struct net_device *netdev,
struct ionic_queue *q,
static struct sk_buff *ionic_rx_frags(struct net_device *netdev,
struct ionic_queue *q,
- struct ionic_desc_info *desc_info,
+ struct ionic_rx_desc_info *desc_info,
unsigned int headroom,
unsigned int len,
unsigned int num_sg_elems,
unsigned int headroom,
unsigned int len,
unsigned int num_sg_elems,
static struct sk_buff *ionic_rx_copybreak(struct net_device *netdev,
struct ionic_queue *q,
static struct sk_buff *ionic_rx_copybreak(struct net_device *netdev,
struct ionic_queue *q,
- struct ionic_desc_info *desc_info,
+ struct ionic_rx_desc_info *desc_info,
unsigned int headroom,
unsigned int len,
bool synced)
unsigned int headroom,
unsigned int len,
bool synced)
}
static void ionic_xdp_tx_desc_clean(struct ionic_queue *q,
}
static void ionic_xdp_tx_desc_clean(struct ionic_queue *q,
- struct ionic_desc_info *desc_info)
+ struct ionic_tx_desc_info *desc_info)
{
unsigned int nbufs = desc_info->nbufs;
struct ionic_buf_info *buf_info;
{
unsigned int nbufs = desc_info->nbufs;
struct ionic_buf_info *buf_info;
enum xdp_action act, struct page *page, int off,
bool ring_doorbell)
{
enum xdp_action act, struct page *page, int off,
bool ring_doorbell)
{
- struct ionic_desc_info *desc_info;
+ struct ionic_tx_desc_info *desc_info;
struct ionic_buf_info *buf_info;
struct ionic_tx_stats *stats;
struct ionic_txq_desc *desc;
struct ionic_buf_info *buf_info;
struct ionic_tx_stats *stats;
struct ionic_txq_desc *desc;
dma_addr_t dma_addr;
u64 cmd;
dma_addr_t dma_addr;
u64 cmd;
- desc_info = &q->info[q->head_idx];
+ desc_info = &q->tx_info[q->head_idx];
desc = &q->txq[q->head_idx];
buf_info = desc_info->bufs;
stats = q_to_tx_stats(q);
desc = &q->txq[q->head_idx];
buf_info = desc_info->bufs;
stats = q_to_tx_stats(q);
stats->pkts++;
stats->bytes += len;
stats->pkts++;
stats->bytes += len;
- ionic_txq_post(q, ring_doorbell, NULL);
+ ionic_txq_post(q, ring_doorbell);
}
static void ionic_rx_clean(struct ionic_queue *q,
}
static void ionic_rx_clean(struct ionic_queue *q,
- struct ionic_desc_info *desc_info,
+ struct ionic_rx_desc_info *desc_info,
struct ionic_rxq_comp *comp)
{
struct net_device *netdev = q->lif->netdev;
struct ionic_rxq_comp *comp)
{
struct net_device *netdev = q->lif->netdev;
bool ionic_rx_service(struct ionic_cq *cq)
{
bool ionic_rx_service(struct ionic_cq *cq)
{
+ struct ionic_rx_desc_info *desc_info;
struct ionic_queue *q = cq->bound_q;
struct ionic_queue *q = cq->bound_q;
- struct ionic_desc_info *desc_info;
struct ionic_rxq_comp *comp;
comp = &((struct ionic_rxq_comp *)cq->base)[cq->tail_idx];
struct ionic_rxq_comp *comp;
comp = &((struct ionic_rxq_comp *)cq->base)[cq->tail_idx];
if (q->tail_idx != le16_to_cpu(comp->comp_index))
return false;
if (q->tail_idx != le16_to_cpu(comp->comp_index))
return false;
- desc_info = &q->info[q->tail_idx];
+ desc_info = &q->rx_info[q->tail_idx];
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
/* clean the related q entry, only one per qc completion */
ionic_rx_clean(q, desc_info, comp);
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
/* clean the related q entry, only one per qc completion */
ionic_rx_clean(q, desc_info, comp);
- desc_info->arg = NULL;
-
void ionic_rx_fill(struct ionic_queue *q)
{
struct net_device *netdev = q->lif->netdev;
void ionic_rx_fill(struct ionic_queue *q)
{
struct net_device *netdev = q->lif->netdev;
- struct ionic_desc_info *desc_info;
+ struct ionic_rx_desc_info *desc_info;
struct ionic_rxq_sg_elem *sg_elem;
struct ionic_buf_info *buf_info;
unsigned int fill_threshold;
struct ionic_rxq_sg_elem *sg_elem;
struct ionic_buf_info *buf_info;
unsigned int fill_threshold;
nfrags = 0;
remain_len = len;
desc = &q->rxq[q->head_idx];
nfrags = 0;
remain_len = len;
desc = &q->rxq[q->head_idx];
- desc_info = &q->info[q->head_idx];
+ desc_info = &q->rx_info[q->head_idx];
buf_info = &desc_info->bufs[0];
if (!buf_info->page) { /* alloc a new buffer? */
buf_info = &desc_info->bufs[0];
if (!buf_info->page) { /* alloc a new buffer? */
ionic_write_cmb_desc(q, desc);
ionic_write_cmb_desc(q, desc);
- ionic_rxq_post(q, false, NULL);
+ ionic_rxq_post(q, false);
}
ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type,
}
ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type,
void ionic_rx_empty(struct ionic_queue *q)
{
void ionic_rx_empty(struct ionic_queue *q)
{
- struct ionic_desc_info *desc_info;
+ struct ionic_rx_desc_info *desc_info;
struct ionic_buf_info *buf_info;
unsigned int i, j;
for (i = 0; i < q->num_descs; i++) {
struct ionic_buf_info *buf_info;
unsigned int i, j;
for (i = 0; i < q->num_descs; i++) {
- desc_info = &q->info[i];
- for (j = 0; j < IONIC_RX_MAX_SG_ELEMS + 1; j++) {
+ desc_info = &q->rx_info[i];
+ for (j = 0; j < ARRAY_SIZE(desc_info->bufs); j++) {
buf_info = &desc_info->bufs[j];
if (buf_info->page)
ionic_rx_page_free(q, buf_info);
}
desc_info->nbufs = 0;
buf_info = &desc_info->bufs[j];
if (buf_info->page)
ionic_rx_page_free(q, buf_info);
}
desc_info->nbufs = 0;
}
static int ionic_tx_map_skb(struct ionic_queue *q, struct sk_buff *skb,
}
static int ionic_tx_map_skb(struct ionic_queue *q, struct sk_buff *skb,
- struct ionic_desc_info *desc_info)
+ struct ionic_tx_desc_info *desc_info)
{
struct ionic_buf_info *buf_info = desc_info->bufs;
struct ionic_tx_stats *stats = q_to_tx_stats(q);
{
struct ionic_buf_info *buf_info = desc_info->bufs;
struct ionic_tx_stats *stats = q_to_tx_stats(q);
}
static void ionic_tx_desc_unmap_bufs(struct ionic_queue *q,
}
static void ionic_tx_desc_unmap_bufs(struct ionic_queue *q,
- struct ionic_desc_info *desc_info)
+ struct ionic_tx_desc_info *desc_info)
{
struct ionic_buf_info *buf_info = desc_info->bufs;
struct device *dev = q->dev;
{
struct ionic_buf_info *buf_info = desc_info->bufs;
struct device *dev = q->dev;
}
static void ionic_tx_clean(struct ionic_queue *q,
}
static void ionic_tx_clean(struct ionic_queue *q,
- struct ionic_desc_info *desc_info,
+ struct ionic_tx_desc_info *desc_info,
struct ionic_txq_comp *comp)
{
struct ionic_tx_stats *stats = q_to_tx_stats(q);
struct ionic_txq_comp *comp)
{
struct ionic_tx_stats *stats = q_to_tx_stats(q);
ionic_tx_desc_unmap_bufs(q, desc_info);
ionic_tx_desc_unmap_bufs(q, desc_info);
static bool ionic_tx_service(struct ionic_cq *cq,
unsigned int *total_pkts, unsigned int *total_bytes)
{
static bool ionic_tx_service(struct ionic_cq *cq,
unsigned int *total_pkts, unsigned int *total_bytes)
{
+ struct ionic_tx_desc_info *desc_info;
struct ionic_queue *q = cq->bound_q;
struct ionic_queue *q = cq->bound_q;
- struct ionic_desc_info *desc_info;
struct ionic_txq_comp *comp;
unsigned int bytes = 0;
unsigned int pkts = 0;
struct ionic_txq_comp *comp;
unsigned int bytes = 0;
unsigned int pkts = 0;
* several q entries completed for each cq completion
*/
do {
* several q entries completed for each cq completion
*/
do {
- desc_info = &q->info[q->tail_idx];
+ desc_info = &q->tx_info[q->tail_idx];
desc_info->bytes = 0;
index = q->tail_idx;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
ionic_tx_clean(q, desc_info, comp);
desc_info->bytes = 0;
index = q->tail_idx;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
ionic_tx_clean(q, desc_info, comp);
pkts++;
bytes += desc_info->bytes;
pkts++;
bytes += desc_info->bytes;
}
} while (index != le16_to_cpu(comp->comp_index));
}
} while (index != le16_to_cpu(comp->comp_index));
void ionic_tx_empty(struct ionic_queue *q)
{
void ionic_tx_empty(struct ionic_queue *q)
{
- struct ionic_desc_info *desc_info;
+ struct ionic_tx_desc_info *desc_info;
int bytes = 0;
int pkts = 0;
/* walk the not completed tx entries, if any */
while (q->head_idx != q->tail_idx) {
int bytes = 0;
int pkts = 0;
/* walk the not completed tx entries, if any */
while (q->head_idx != q->tail_idx) {
- desc_info = &q->info[q->tail_idx];
+ desc_info = &q->tx_info[q->tail_idx];
desc_info->bytes = 0;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
ionic_tx_clean(q, desc_info, NULL);
desc_info->bytes = 0;
q->tail_idx = (q->tail_idx + 1) & (q->num_descs - 1);
ionic_tx_clean(q, desc_info, NULL);
pkts++;
bytes += desc_info->bytes;
pkts++;
bytes += desc_info->bytes;
}
static void ionic_tx_tso_post(struct net_device *netdev, struct ionic_queue *q,
}
static void ionic_tx_tso_post(struct net_device *netdev, struct ionic_queue *q,
- struct ionic_desc_info *desc_info,
+ struct ionic_tx_desc_info *desc_info,
struct sk_buff *skb,
dma_addr_t addr, u8 nsge, u16 len,
unsigned int hdrlen, unsigned int mss,
struct sk_buff *skb,
dma_addr_t addr, u8 nsge, u16 len,
unsigned int hdrlen, unsigned int mss,
skb_tx_timestamp(skb);
if (likely(!ionic_txq_hwstamp_enabled(q)))
netdev_tx_sent_queue(q_to_ndq(netdev, q), skb->len);
skb_tx_timestamp(skb);
if (likely(!ionic_txq_hwstamp_enabled(q)))
netdev_tx_sent_queue(q_to_ndq(netdev, q), skb->len);
- ionic_txq_post(q, false, skb);
+ ionic_txq_post(q, false);
- ionic_txq_post(q, done, NULL);
+ ionic_txq_post(q, done);
struct sk_buff *skb)
{
struct ionic_tx_stats *stats = q_to_tx_stats(q);
struct sk_buff *skb)
{
struct ionic_tx_stats *stats = q_to_tx_stats(q);
- struct ionic_desc_info *desc_info;
+ struct ionic_tx_desc_info *desc_info;
struct ionic_buf_info *buf_info;
struct ionic_txq_sg_elem *elem;
struct ionic_txq_desc *desc;
struct ionic_buf_info *buf_info;
struct ionic_txq_sg_elem *elem;
struct ionic_txq_desc *desc;
- desc_info = &q->info[q->head_idx];
- buf_info = desc_info->bufs;
+ desc_info = &q->tx_info[q->head_idx];
if (unlikely(ionic_tx_map_skb(q, skb, desc_info)))
return -EIO;
if (unlikely(ionic_tx_map_skb(q, skb, desc_info)))
return -EIO;
else
hdrlen = skb_tcp_all_headers(skb);
else
hdrlen = skb_tcp_all_headers(skb);
+ desc_info->skb = skb;
+ buf_info = desc_info->bufs;
tso_rem = len;
seg_rem = min(tso_rem, hdrlen + mss);
tso_rem = len;
seg_rem = min(tso_rem, hdrlen + mss);
start, done);
start = false;
/* Buffer information is stored with the first tso descriptor */
start, done);
start = false;
/* Buffer information is stored with the first tso descriptor */
- desc_info = &q->info[q->head_idx];
+ desc_info = &q->tx_info[q->head_idx];
}
static void ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb,
}
static void ionic_tx_calc_csum(struct ionic_queue *q, struct sk_buff *skb,
- struct ionic_desc_info *desc_info)
+ struct ionic_tx_desc_info *desc_info)
{
struct ionic_txq_desc *desc = &q->txq[q->head_idx];
struct ionic_buf_info *buf_info = desc_info->bufs;
{
struct ionic_txq_desc *desc = &q->txq[q->head_idx];
struct ionic_buf_info *buf_info = desc_info->bufs;
}
static void ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb,
}
static void ionic_tx_calc_no_csum(struct ionic_queue *q, struct sk_buff *skb,
- struct ionic_desc_info *desc_info)
+ struct ionic_tx_desc_info *desc_info)
{
struct ionic_txq_desc *desc = &q->txq[q->head_idx];
struct ionic_buf_info *buf_info = desc_info->bufs;
{
struct ionic_txq_desc *desc = &q->txq[q->head_idx];
struct ionic_buf_info *buf_info = desc_info->bufs;
}
static void ionic_tx_skb_frags(struct ionic_queue *q, struct sk_buff *skb,
}
static void ionic_tx_skb_frags(struct ionic_queue *q, struct sk_buff *skb,
- struct ionic_desc_info *desc_info)
+ struct ionic_tx_desc_info *desc_info)
{
struct ionic_buf_info *buf_info = &desc_info->bufs[1];
struct ionic_tx_stats *stats = q_to_tx_stats(q);
{
struct ionic_buf_info *buf_info = &desc_info->bufs[1];
struct ionic_tx_stats *stats = q_to_tx_stats(q);
static int ionic_tx(struct net_device *netdev, struct ionic_queue *q,
struct sk_buff *skb)
{
static int ionic_tx(struct net_device *netdev, struct ionic_queue *q,
struct sk_buff *skb)
{
- struct ionic_desc_info *desc_info = &q->info[q->head_idx];
+ struct ionic_tx_desc_info *desc_info = &q->tx_info[q->head_idx];
struct ionic_tx_stats *stats = q_to_tx_stats(q);
bool ring_dbell = true;
if (unlikely(ionic_tx_map_skb(q, skb, desc_info)))
return -EIO;
struct ionic_tx_stats *stats = q_to_tx_stats(q);
bool ring_dbell = true;
if (unlikely(ionic_tx_map_skb(q, skb, desc_info)))
return -EIO;
+ desc_info->skb = skb;
+
/* set up the initial descriptor */
if (skb->ip_summed == CHECKSUM_PARTIAL)
ionic_tx_calc_csum(q, skb, desc_info);
/* set up the initial descriptor */
if (skb->ip_summed == CHECKSUM_PARTIAL)
ionic_tx_calc_csum(q, skb, desc_info);
ring_dbell = __netdev_tx_sent_queue(ndq, skb->len,
netdev_xmit_more());
}
ring_dbell = __netdev_tx_sent_queue(ndq, skb->len,
netdev_xmit_more());
}
- ionic_txq_post(q, ring_dbell, skb);
+ ionic_txq_post(q, ring_dbell);