Skip to content

Commit 3d7d562

Browse files
Yuval Mintzdavem330
authored andcommitted
bnx2x: Add ndo_get_phys_port_id support
Each network interface (either PF or VF) is identified by its port's MAC id. Signed-off-by: Yuval Mintz <[email protected]> Signed-off-by: Ariel Elior <[email protected]> Signed-off-by: Eilon Greenstein <[email protected]> Signed-off-by: David S. Miller <[email protected]>
1 parent c2bb06d commit 3d7d562

File tree

4 files changed

+155
-27
lines changed

4 files changed

+155
-27
lines changed

drivers/net/ethernet/broadcom/bnx2x/bnx2x.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1546,6 +1546,7 @@ struct bnx2x {
15461546
#define IS_VF_FLAG (1 << 22)
15471547
#define INTERRUPTS_ENABLED_FLAG (1 << 23)
15481548
#define BC_SUPPORTS_RMMOD_CMD (1 << 24)
1549+
#define HAS_PHYS_PORT_ID (1 << 25)
15491550

15501551
#define BP_NOMCP(bp) ((bp)->flags & NO_MCP_FLAG)
15511552

@@ -1876,6 +1877,8 @@ struct bnx2x {
18761877
u32 dump_preset_idx;
18771878
bool stats_started;
18781879
struct semaphore stats_sema;
1880+
1881+
u8 phys_port_id[ETH_ALEN];
18791882
};
18801883

18811884
/* Tx queues may be less or equal to Rx queues */

drivers/net/ethernet/broadcom/bnx2x/bnx2x_main.c

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11149,6 +11149,14 @@ static void bnx2x_get_mac_hwinfo(struct bnx2x *bp)
1114911149
bnx2x_get_cnic_mac_hwinfo(bp);
1115011150
}
1115111151

11152+
if (!BP_NOMCP(bp)) {
11153+
/* Read physical port identifier from shmem */
11154+
val2 = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_upper);
11155+
val = SHMEM_RD(bp, dev_info.port_hw_config[port].mac_lower);
11156+
bnx2x_set_mac_buf(bp->phys_port_id, val, val2);
11157+
bp->flags |= HAS_PHYS_PORT_ID;
11158+
}
11159+
1115211160
memcpy(bp->link_params.mac_addr, bp->dev->dev_addr, ETH_ALEN);
1115311161

1115411162
if (!bnx2x_is_valid_ether_addr(bp, bp->dev->dev_addr))
@@ -12044,6 +12052,20 @@ static int bnx2x_validate_addr(struct net_device *dev)
1204412052
return 0;
1204512053
}
1204612054

12055+
static int bnx2x_get_phys_port_id(struct net_device *netdev,
12056+
struct netdev_phys_port_id *ppid)
12057+
{
12058+
struct bnx2x *bp = netdev_priv(netdev);
12059+
12060+
if (!(bp->flags & HAS_PHYS_PORT_ID))
12061+
return -EOPNOTSUPP;
12062+
12063+
ppid->id_len = sizeof(bp->phys_port_id);
12064+
memcpy(ppid->id, bp->phys_port_id, ppid->id_len);
12065+
12066+
return 0;
12067+
}
12068+
1204712069
static const struct net_device_ops bnx2x_netdev_ops = {
1204812070
.ndo_open = bnx2x_open,
1204912071
.ndo_stop = bnx2x_close,
@@ -12073,6 +12095,7 @@ static const struct net_device_ops bnx2x_netdev_ops = {
1207312095
#ifdef CONFIG_NET_RX_BUSY_POLL
1207412096
.ndo_busy_poll = bnx2x_low_latency_recv,
1207512097
#endif
12098+
.ndo_get_phys_port_id = bnx2x_get_phys_port_id,
1207612099
};
1207712100

1207812101
static int bnx2x_set_coherency_mask(struct bnx2x *bp)

drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.c

Lines changed: 122 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,30 @@ void bnx2x_vfpf_finalize(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv)
6060
mutex_unlock(&bp->vf2pf_mutex);
6161
}
6262

63+
/* Finds a TLV by type in a TLV buffer; If found, returns pointer to the TLV */
64+
static void *bnx2x_search_tlv_list(struct bnx2x *bp, void *tlvs_list,
65+
enum channel_tlvs req_tlv)
66+
{
67+
struct channel_tlv *tlv = (struct channel_tlv *)tlvs_list;
68+
69+
do {
70+
if (tlv->type == req_tlv)
71+
return tlv;
72+
73+
if (!tlv->length) {
74+
BNX2X_ERR("Found TLV with length 0\n");
75+
return NULL;
76+
}
77+
78+
tlvs_list += tlv->length;
79+
tlv = (struct channel_tlv *)tlvs_list;
80+
} while (tlv->type != CHANNEL_TLV_LIST_END);
81+
82+
DP(BNX2X_MSG_IOV, "TLV list does not contain %d TLV\n", req_tlv);
83+
84+
return NULL;
85+
}
86+
6387
/* list the types and lengths of the tlvs on the buffer */
6488
void bnx2x_dp_tlv_list(struct bnx2x *bp, void *tlvs_list)
6589
{
@@ -196,6 +220,7 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
196220
int rc = 0, attempts = 0;
197221
struct vfpf_acquire_tlv *req = &bp->vf2pf_mbox->req.acquire;
198222
struct pfvf_acquire_resp_tlv *resp = &bp->vf2pf_mbox->resp.acquire_resp;
223+
struct vfpf_port_phys_id_resp_tlv *phys_port_resp;
199224
u32 vf_id;
200225
bool resources_acquired = false;
201226

@@ -219,8 +244,14 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
219244
/* pf 2 vf bulletin board address */
220245
req->bulletin_addr = bp->pf2vf_bulletin_mapping;
221246

247+
/* Request physical port identifier */
248+
bnx2x_add_tlv(bp, req, req->first_tlv.tl.length,
249+
CHANNEL_TLV_PHYS_PORT_ID, sizeof(struct channel_tlv));
250+
222251
/* add list termination tlv */
223-
bnx2x_add_tlv(bp, req, req->first_tlv.tl.length, CHANNEL_TLV_LIST_END,
252+
bnx2x_add_tlv(bp, req,
253+
req->first_tlv.tl.length + sizeof(struct channel_tlv),
254+
CHANNEL_TLV_LIST_END,
224255
sizeof(struct channel_list_end_tlv));
225256

226257
/* output tlvs list */
@@ -287,6 +318,15 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
287318
}
288319
}
289320

321+
/* Retrieve physical port id (if possible) */
322+
phys_port_resp = (struct vfpf_port_phys_id_resp_tlv *)
323+
bnx2x_search_tlv_list(bp, resp,
324+
CHANNEL_TLV_PHYS_PORT_ID);
325+
if (phys_port_resp) {
326+
memcpy(bp->phys_port_id, phys_port_resp->id, ETH_ALEN);
327+
bp->flags |= HAS_PHYS_PORT_ID;
328+
}
329+
290330
/* get HW info */
291331
bp->common.chip_id |= (bp->acquire_resp.pfdev_info.chip_num & 0xffff);
292332
bp->link_params.chip_id = bp->common.chip_id;
@@ -983,53 +1023,59 @@ static int bnx2x_copy32_vf_dmae(struct bnx2x *bp, u8 from_vf,
9831023
return bnx2x_issue_dmae_with_comp(bp, &dmae);
9841024
}
9851025

986-
static void bnx2x_vf_mbx_resp(struct bnx2x *bp, struct bnx2x_virtf *vf)
1026+
static void bnx2x_vf_mbx_resp_single_tlv(struct bnx2x *bp,
1027+
struct bnx2x_virtf *vf)
9871028
{
9881029
struct bnx2x_vf_mbx *mbx = BP_VF_MBX(bp, vf->index);
989-
u64 vf_addr;
990-
dma_addr_t pf_addr;
9911030
u16 length, type;
992-
int rc;
993-
struct pfvf_general_resp_tlv *resp = &mbx->msg->resp.general_resp;
9941031

9951032
/* prepare response */
9961033
type = mbx->first_tlv.tl.type;
9971034
length = type == CHANNEL_TLV_ACQUIRE ?
9981035
sizeof(struct pfvf_acquire_resp_tlv) :
9991036
sizeof(struct pfvf_general_resp_tlv);
1000-
bnx2x_add_tlv(bp, resp, 0, type, length);
1001-
resp->hdr.status = bnx2x_pfvf_status_codes(vf->op_rc);
1002-
bnx2x_add_tlv(bp, resp, length, CHANNEL_TLV_LIST_END,
1037+
bnx2x_add_tlv(bp, &mbx->msg->resp, 0, type, length);
1038+
bnx2x_add_tlv(bp, &mbx->msg->resp, length, CHANNEL_TLV_LIST_END,
10031039
sizeof(struct channel_list_end_tlv));
1040+
}
1041+
1042+
static void bnx2x_vf_mbx_resp_send_msg(struct bnx2x *bp,
1043+
struct bnx2x_virtf *vf)
1044+
{
1045+
struct bnx2x_vf_mbx *mbx = BP_VF_MBX(bp, vf->index);
1046+
struct pfvf_general_resp_tlv *resp = &mbx->msg->resp.general_resp;
1047+
dma_addr_t pf_addr;
1048+
u64 vf_addr;
1049+
int rc;
1050+
10041051
bnx2x_dp_tlv_list(bp, resp);
10051052
DP(BNX2X_MSG_IOV, "mailbox vf address hi 0x%x, lo 0x%x, offset 0x%x\n",
10061053
mbx->vf_addr_hi, mbx->vf_addr_lo, mbx->first_tlv.resp_msg_offset);
10071054

1055+
resp->hdr.status = bnx2x_pfvf_status_codes(vf->op_rc);
1056+
10081057
/* send response */
10091058
vf_addr = HILO_U64(mbx->vf_addr_hi, mbx->vf_addr_lo) +
10101059
mbx->first_tlv.resp_msg_offset;
10111060
pf_addr = mbx->msg_mapping +
10121061
offsetof(struct bnx2x_vf_mbx_msg, resp);
10131062

1014-
/* copy the response body, if there is one, before the header, as the vf
1015-
* is sensitive to the header being written
1063+
/* Copy the response buffer. The first u64 is written afterwards, as
1064+
* the vf is sensitive to the header being written
10161065
*/
1017-
if (resp->hdr.tl.length > sizeof(u64)) {
1018-
length = resp->hdr.tl.length - sizeof(u64);
1019-
vf_addr += sizeof(u64);
1020-
pf_addr += sizeof(u64);
1021-
rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr, vf->abs_vfid,
1022-
U64_HI(vf_addr),
1023-
U64_LO(vf_addr),
1024-
length/4);
1025-
if (rc) {
1026-
BNX2X_ERR("Failed to copy response body to VF %d\n",
1027-
vf->abs_vfid);
1028-
goto mbx_error;
1029-
}
1030-
vf_addr -= sizeof(u64);
1031-
pf_addr -= sizeof(u64);
1066+
vf_addr += sizeof(u64);
1067+
pf_addr += sizeof(u64);
1068+
rc = bnx2x_copy32_vf_dmae(bp, false, pf_addr, vf->abs_vfid,
1069+
U64_HI(vf_addr),
1070+
U64_LO(vf_addr),
1071+
(sizeof(union pfvf_tlvs) - sizeof(u64))/4);
1072+
if (rc) {
1073+
BNX2X_ERR("Failed to copy response body to VF %d\n",
1074+
vf->abs_vfid);
1075+
goto mbx_error;
10321076
}
1077+
vf_addr -= sizeof(u64);
1078+
pf_addr -= sizeof(u64);
10331079

10341080
/* ack the FW */
10351081
storm_memset_vf_mbx_ack(bp, vf->abs_vfid);
@@ -1060,13 +1106,44 @@ static void bnx2x_vf_mbx_resp(struct bnx2x *bp, struct bnx2x_virtf *vf)
10601106
bnx2x_vf_release(bp, vf, false); /* non blocking */
10611107
}
10621108

1109+
static void bnx2x_vf_mbx_resp(struct bnx2x *bp,
1110+
struct bnx2x_virtf *vf)
1111+
{
1112+
bnx2x_vf_mbx_resp_single_tlv(bp, vf);
1113+
bnx2x_vf_mbx_resp_send_msg(bp, vf);
1114+
}
1115+
1116+
static void bnx2x_vf_mbx_resp_phys_port(struct bnx2x *bp,
1117+
struct bnx2x_virtf *vf,
1118+
void *buffer,
1119+
u16 *offset)
1120+
{
1121+
struct vfpf_port_phys_id_resp_tlv *port_id;
1122+
1123+
if (!(bp->flags & HAS_PHYS_PORT_ID))
1124+
return;
1125+
1126+
bnx2x_add_tlv(bp, buffer, *offset, CHANNEL_TLV_PHYS_PORT_ID,
1127+
sizeof(struct vfpf_port_phys_id_resp_tlv));
1128+
1129+
port_id = (struct vfpf_port_phys_id_resp_tlv *)
1130+
(((u8 *)buffer) + *offset);
1131+
memcpy(port_id->id, bp->phys_port_id, ETH_ALEN);
1132+
1133+
/* Offset should continue representing the offset to the tail
1134+
* of TLV data (outside this function scope)
1135+
*/
1136+
*offset += sizeof(struct vfpf_port_phys_id_resp_tlv);
1137+
}
1138+
10631139
static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
10641140
struct bnx2x_vf_mbx *mbx, int vfop_status)
10651141
{
10661142
int i;
10671143
struct pfvf_acquire_resp_tlv *resp = &mbx->msg->resp.acquire_resp;
10681144
struct pf_vf_resc *resc = &resp->resc;
10691145
u8 status = bnx2x_pfvf_status_codes(vfop_status);
1146+
u16 length;
10701147

10711148
memset(resp, 0, sizeof(*resp));
10721149

@@ -1140,9 +1217,24 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
11401217
resc->hw_sbs[i].sb_qid);
11411218
DP_CONT(BNX2X_MSG_IOV, "]\n");
11421219

1220+
/* prepare response */
1221+
length = sizeof(struct pfvf_acquire_resp_tlv);
1222+
bnx2x_add_tlv(bp, &mbx->msg->resp, 0, CHANNEL_TLV_ACQUIRE, length);
1223+
1224+
/* Handle possible VF requests for physical port identifiers.
1225+
* 'length' should continue to indicate the offset of the first empty
1226+
* place in the buffer (i.e., where next TLV should be inserted)
1227+
*/
1228+
if (bnx2x_search_tlv_list(bp, &mbx->msg->req,
1229+
CHANNEL_TLV_PHYS_PORT_ID))
1230+
bnx2x_vf_mbx_resp_phys_port(bp, vf, &mbx->msg->resp, &length);
1231+
1232+
bnx2x_add_tlv(bp, &mbx->msg->resp, length, CHANNEL_TLV_LIST_END,
1233+
sizeof(struct channel_list_end_tlv));
1234+
11431235
/* send the response */
11441236
vf->op_rc = vfop_status;
1145-
bnx2x_vf_mbx_resp(bp, vf);
1237+
bnx2x_vf_mbx_resp_send_msg(bp, vf);
11461238
}
11471239

11481240
static void bnx2x_vf_mbx_acquire(struct bnx2x *bp, struct bnx2x_virtf *vf,
@@ -1874,6 +1966,9 @@ void bnx2x_vf_mbx(struct bnx2x *bp, struct vf_pf_event_data *vfpf_event)
18741966
/* process the VF message header */
18751967
mbx->first_tlv = mbx->msg->req.first_tlv;
18761968

1969+
/* Clean response buffer to refrain from falsely seeing chains */
1970+
memset(&mbx->msg->resp, 0, sizeof(union pfvf_tlvs));
1971+
18771972
/* dispatch the request (will prepare the response) */
18781973
bnx2x_vf_mbx_request(bp, vf, mbx);
18791974
goto mbx_done;

drivers/net/ethernet/broadcom/bnx2x/bnx2x_vfpf.h

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -188,6 +188,12 @@ struct pfvf_acquire_resp_tlv {
188188
} resc;
189189
};
190190

191+
struct vfpf_port_phys_id_resp_tlv {
192+
struct channel_tlv tl;
193+
u8 id[ETH_ALEN];
194+
u8 padding[2];
195+
};
196+
191197
#define VFPF_INIT_FLG_STATS_COALESCE (1 << 0) /* when set the VFs queues
192198
* stats will be coalesced on
193199
* the leading RSS queue
@@ -398,6 +404,7 @@ enum channel_tlvs {
398404
CHANNEL_TLV_PF_SET_MAC,
399405
CHANNEL_TLV_PF_SET_VLAN,
400406
CHANNEL_TLV_UPDATE_RSS,
407+
CHANNEL_TLV_PHYS_PORT_ID,
401408
CHANNEL_TLV_MAX
402409
};
403410

0 commit comments

Comments
 (0)