1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
|
/* SPDX-License-Identifier: GPL-2.0 */
/* Copyright (c) Meta Platforms, Inc. and affiliates. */
#ifndef _FBNIC_H_
#define _FBNIC_H_
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/types.h>
#include <linux/workqueue.h>
#include "fbnic_csr.h"
#include "fbnic_fw.h"
#include "fbnic_mac.h"
#include "fbnic_rpc.h"
struct fbnic_dev {
struct device *dev;
struct net_device *netdev;
u32 __iomem *uc_addr0;
u32 __iomem *uc_addr4;
const struct fbnic_mac *mac;
unsigned int fw_msix_vector;
unsigned int pcs_msix_vector;
unsigned short num_irqs;
struct delayed_work service_task;
struct fbnic_fw_mbx mbx[FBNIC_IPC_MBX_INDICES];
struct fbnic_fw_cap fw_cap;
/* Lock protecting Tx Mailbox queue to prevent possible races */
spinlock_t fw_tx_lock;
unsigned long last_heartbeat_request;
unsigned long last_heartbeat_response;
u8 fw_heartbeat_enabled;
u64 dsn;
u32 mps;
u32 readrq;
/* Local copy of the devices TCAM */
struct fbnic_act_tcam act_tcam[FBNIC_RPC_TCAM_ACT_NUM_ENTRIES];
struct fbnic_mac_addr mac_addr[FBNIC_RPC_TCAM_MACDA_NUM_ENTRIES];
u8 mac_addr_boundary;
/* Number of TCQs/RCQs available on hardware */
u16 max_num_queues;
};
/* Reserve entry 0 in the MSI-X "others" array until we have filled all
* 32 of the possible interrupt slots. By doing this we can avoid any
* potential conflicts should we need to enable one of the debug interrupt
* causes later.
*/
enum {
FBNIC_FW_MSIX_ENTRY,
FBNIC_PCS_MSIX_ENTRY,
FBNIC_NON_NAPI_VECTORS
};
static inline bool fbnic_present(struct fbnic_dev *fbd)
{
return !!READ_ONCE(fbd->uc_addr0);
}
static inline void fbnic_wr32(struct fbnic_dev *fbd, u32 reg, u32 val)
{
u32 __iomem *csr = READ_ONCE(fbd->uc_addr0);
if (csr)
writel(val, csr + reg);
}
u32 fbnic_rd32(struct fbnic_dev *fbd, u32 reg);
static inline void fbnic_wrfl(struct fbnic_dev *fbd)
{
fbnic_rd32(fbd, FBNIC_MASTER_SPARE_0);
}
static inline void
fbnic_rmw32(struct fbnic_dev *fbd, u32 reg, u32 mask, u32 val)
{
u32 v;
v = fbnic_rd32(fbd, reg);
v &= ~mask;
v |= val;
fbnic_wr32(fbd, reg, v);
}
#define wr32(_f, _r, _v) fbnic_wr32(_f, _r, _v)
#define rd32(_f, _r) fbnic_rd32(_f, _r)
#define wrfl(_f) fbnic_wrfl(_f)
bool fbnic_fw_present(struct fbnic_dev *fbd);
u32 fbnic_fw_rd32(struct fbnic_dev *fbd, u32 reg);
void fbnic_fw_wr32(struct fbnic_dev *fbd, u32 reg, u32 val);
#define fw_rd32(_f, _r) fbnic_fw_rd32(_f, _r)
#define fw_wr32(_f, _r, _v) fbnic_fw_wr32(_f, _r, _v)
#define fw_wrfl(_f) fbnic_fw_rd32(_f, FBNIC_FW_ZERO_REG)
static inline bool fbnic_bmc_present(struct fbnic_dev *fbd)
{
return fbd->fw_cap.bmc_present;
}
static inline bool fbnic_init_failure(struct fbnic_dev *fbd)
{
return !fbd->netdev;
}
extern char fbnic_driver_name[];
void fbnic_devlink_free(struct fbnic_dev *fbd);
struct fbnic_dev *fbnic_devlink_alloc(struct pci_dev *pdev);
void fbnic_devlink_register(struct fbnic_dev *fbd);
void fbnic_devlink_unregister(struct fbnic_dev *fbd);
int fbnic_fw_enable_mbx(struct fbnic_dev *fbd);
void fbnic_fw_disable_mbx(struct fbnic_dev *fbd);
int fbnic_pcs_irq_enable(struct fbnic_dev *fbd);
void fbnic_pcs_irq_disable(struct fbnic_dev *fbd);
int fbnic_request_irq(struct fbnic_dev *dev, int nr, irq_handler_t handler,
unsigned long flags, const char *name, void *data);
void fbnic_free_irq(struct fbnic_dev *dev, int nr, void *data);
void fbnic_free_irqs(struct fbnic_dev *fbd);
int fbnic_alloc_irqs(struct fbnic_dev *fbd);
enum fbnic_boards {
fbnic_board_asic
};
struct fbnic_info {
unsigned int max_num_queues;
unsigned int bar_mask;
};
#endif /* _FBNIC_H_ */
|