Commit dd2a0ff5 authored by FUJITA Tomonori's avatar FUJITA Tomonori Committed by Jakub Kicinski

net: tn40xx: add basic Tx handling

This patch adds device specific structures to initialize the hardware
with basic Tx handling. The original driver loads the embedded
firmware in the header file. This driver is implemented to use the
firmware APIs.

The Tx logic uses three major data structures; two ring buffers with
NIC and one database. One ring buffer is used to send information
about packets to be sent for NIC. The other is used to get information
from NIC about packet that are sent. The database is used to keep the
information about DMA mapping. After a packet is sent, the db is used
to free the resource used for the packet.
Signed-off-by: default avatarFUJITA Tomonori <fujita.tomonori@gmail.com>
Link: https://patch.msgid.link/20240623235507.108147-5-fujita.tomonori@gmail.comSigned-off-by: default avatarJakub Kicinski <kuba@kernel.org>
parent ffa28c74
......@@ -26,6 +26,7 @@ config TEHUTI
config TEHUTI_TN40
tristate "Tehuti Networks TN40xx 10G Ethernet adapters"
depends on PCI
select FW_LOADER
help
This driver supports 10G Ethernet adapters using Tehuti Networks
TN40xx chips. Currently, adapters with Applied Micro Circuits
......
This diff is collapsed.
......@@ -8,4 +8,161 @@
#define TN40_DRV_NAME "tn40xx"
#define TN40_MDIO_SPEED_1MHZ (1)
#define TN40_MDIO_SPEED_6MHZ (6)
/* netdev tx queue len for Luxor. The default value is 1000.
* ifconfig eth1 txqueuelen 3000 - to change it at runtime.
*/
#define TN40_NDEV_TXQ_LEN 1000
#define TN40_FIFO_SIZE 4096
#define TN40_FIFO_EXTRA_SPACE 1024
#define TN40_TXF_DESC_SZ 16
#define TN40_MAX_TX_LEVEL (priv->txd_fifo0.m.memsz - 16)
#define TN40_MIN_TX_LEVEL 256
#define TN40_NO_UPD_PACKETS 40
#define TN40_MAX_MTU BIT(14)
#define TN40_PCK_TH_MULT 128
#define TN40_INT_COAL_MULT 2
#define TN40_INT_REG_VAL(coal, coal_rc, rxf_th, pck_th) ( \
FIELD_PREP(GENMASK(14, 0), (coal)) | \
FIELD_PREP(BIT(15), (coal_rc)) | \
FIELD_PREP(GENMASK(19, 16), (rxf_th)) | \
FIELD_PREP(GENMASK(31, 20), (pck_th)) \
)
struct tn40_fifo {
dma_addr_t da; /* Physical address of fifo (used by HW) */
char *va; /* Virtual address of fifo (used by SW) */
u32 rptr, wptr;
/* Cached values of RPTR and WPTR registers,
* they're 32 bits on both 32 and 64 archs.
*/
u16 reg_cfg0;
u16 reg_cfg1;
u16 reg_rptr;
u16 reg_wptr;
u16 memsz; /* Memory size allocated for fifo */
u16 size_mask;
u16 pktsz; /* Skb packet size to allocate */
u16 rcvno; /* Number of buffers that come from this RXF */
};
struct tn40_txf_fifo {
struct tn40_fifo m; /* The minimal set of variables used by all fifos */
};
struct tn40_txd_fifo {
struct tn40_fifo m; /* The minimal set of variables used by all fifos */
};
union tn40_tx_dma_addr {
dma_addr_t dma;
struct sk_buff *skb;
};
/* Entry in the db.
* if len == 0 addr is dma
* if len != 0 addr is skb
*/
struct tn40_tx_map {
union tn40_tx_dma_addr addr;
int len;
};
/* tx database - implemented as circular fifo buffer */
struct tn40_txdb {
struct tn40_tx_map *start; /* Points to the first element */
struct tn40_tx_map *end; /* Points just AFTER the last element */
struct tn40_tx_map *rptr; /* Points to the next element to read */
struct tn40_tx_map *wptr; /* Points to the next element to write */
int size; /* Number of elements in the db */
};
struct tn40_priv {
struct net_device *ndev;
struct pci_dev *pdev;
/* Tx FIFOs: 1 for data desc, 1 for empty (acks) desc */
struct tn40_txd_fifo txd_fifo0;
struct tn40_txf_fifo txf_fifo0;
struct tn40_txdb txdb;
int tx_level;
int tx_update_mark;
int tx_noupd;
int stats_flag;
struct rtnl_link_stats64 stats;
struct u64_stats_sync syncp;
u8 txd_size;
u8 txf_size;
u8 rxd_size;
u8 rxf_size;
u32 rdintcm;
u32 tdintcm;
u32 isr_mask;
void __iomem *regs;
/* SHORT_PKT_FIX */
u32 b0_len;
dma_addr_t b0_dma; /* Physical address of buffer */
char *b0_va; /* Virtual address of buffer */
};
#define TN40_MAX_PBL (19)
/* PBL describes each virtual buffer to be transmitted from the host. */
struct tn40_pbl {
__le32 pa_lo;
__le32 pa_hi;
__le32 len;
};
/* First word for TXD descriptor. It means: type = 3 for regular Tx packet,
* hw_csum = 7 for IP+UDP+TCP HW checksums.
*/
#define TN40_TXD_W1_VAL(bc, checksum, vtag, lgsnd, vlan_id) ( \
GENMASK(17, 16) | \
FIELD_PREP(GENMASK(4, 0), (bc)) | \
FIELD_PREP(GENMASK(7, 5), (checksum)) | \
FIELD_PREP(BIT(8), (vtag)) | \
FIELD_PREP(GENMASK(12, 9), (lgsnd)) | \
FIELD_PREP(GENMASK(15, 13), \
FIELD_GET(GENMASK(15, 13), (vlan_id))) | \
FIELD_PREP(GENMASK(31, 20), \
FIELD_GET(GENMASK(11, 0), (vlan_id))) \
)
struct tn40_txd_desc {
__le32 txd_val1;
__le16 mss;
__le16 length;
__le32 va_lo;
__le32 va_hi;
struct tn40_pbl pbl[]; /* Fragments */
};
struct tn40_txf_desc {
u32 status;
u32 va_lo; /* VAdr[31:0] */
u32 va_hi; /* VAdr[63:32] */
u32 pad;
};
static inline u32 tn40_read_reg(struct tn40_priv *priv, u32 reg)
{
return readl(priv->regs + reg);
}
static inline void tn40_write_reg(struct tn40_priv *priv, u32 reg, u32 val)
{
writel(val, priv->regs + reg);
}
#endif /* _TN40XX_H */
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment