@@ -60,6 +60,30 @@ void bnx2x_vfpf_finalize(struct bnx2x *bp, struct vfpf_first_tlv *first_tlv)
60
60
mutex_unlock (& bp -> vf2pf_mutex );
61
61
}
62
62
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
+
63
87
/* list the types and lengths of the tlvs on the buffer */
64
88
void bnx2x_dp_tlv_list (struct bnx2x * bp , void * tlvs_list )
65
89
{
@@ -196,6 +220,7 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
196
220
int rc = 0 , attempts = 0 ;
197
221
struct vfpf_acquire_tlv * req = & bp -> vf2pf_mbox -> req .acquire ;
198
222
struct pfvf_acquire_resp_tlv * resp = & bp -> vf2pf_mbox -> resp .acquire_resp ;
223
+ struct vfpf_port_phys_id_resp_tlv * phys_port_resp ;
199
224
u32 vf_id ;
200
225
bool resources_acquired = false;
201
226
@@ -219,8 +244,14 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
219
244
/* pf 2 vf bulletin board address */
220
245
req -> bulletin_addr = bp -> pf2vf_bulletin_mapping ;
221
246
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
+
222
251
/* 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 ,
224
255
sizeof (struct channel_list_end_tlv ));
225
256
226
257
/* output tlvs list */
@@ -287,6 +318,15 @@ int bnx2x_vfpf_acquire(struct bnx2x *bp, u8 tx_count, u8 rx_count)
287
318
}
288
319
}
289
320
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
+
290
330
/* get HW info */
291
331
bp -> common .chip_id |= (bp -> acquire_resp .pfdev_info .chip_num & 0xffff );
292
332
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,
983
1023
return bnx2x_issue_dmae_with_comp (bp , & dmae );
984
1024
}
985
1025
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 )
987
1028
{
988
1029
struct bnx2x_vf_mbx * mbx = BP_VF_MBX (bp , vf -> index );
989
- u64 vf_addr ;
990
- dma_addr_t pf_addr ;
991
1030
u16 length , type ;
992
- int rc ;
993
- struct pfvf_general_resp_tlv * resp = & mbx -> msg -> resp .general_resp ;
994
1031
995
1032
/* prepare response */
996
1033
type = mbx -> first_tlv .tl .type ;
997
1034
length = type == CHANNEL_TLV_ACQUIRE ?
998
1035
sizeof (struct pfvf_acquire_resp_tlv ) :
999
1036
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 ,
1003
1039
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
+
1004
1051
bnx2x_dp_tlv_list (bp , resp );
1005
1052
DP (BNX2X_MSG_IOV , "mailbox vf address hi 0x%x, lo 0x%x, offset 0x%x\n" ,
1006
1053
mbx -> vf_addr_hi , mbx -> vf_addr_lo , mbx -> first_tlv .resp_msg_offset );
1007
1054
1055
+ resp -> hdr .status = bnx2x_pfvf_status_codes (vf -> op_rc );
1056
+
1008
1057
/* send response */
1009
1058
vf_addr = HILO_U64 (mbx -> vf_addr_hi , mbx -> vf_addr_lo ) +
1010
1059
mbx -> first_tlv .resp_msg_offset ;
1011
1060
pf_addr = mbx -> msg_mapping +
1012
1061
offsetof(struct bnx2x_vf_mbx_msg , resp );
1013
1062
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
1016
1065
*/
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 ;
1032
1076
}
1077
+ vf_addr -= sizeof (u64 );
1078
+ pf_addr -= sizeof (u64 );
1033
1079
1034
1080
/* ack the FW */
1035
1081
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)
1060
1106
bnx2x_vf_release (bp , vf , false); /* non blocking */
1061
1107
}
1062
1108
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
+
1063
1139
static void bnx2x_vf_mbx_acquire_resp (struct bnx2x * bp , struct bnx2x_virtf * vf ,
1064
1140
struct bnx2x_vf_mbx * mbx , int vfop_status )
1065
1141
{
1066
1142
int i ;
1067
1143
struct pfvf_acquire_resp_tlv * resp = & mbx -> msg -> resp .acquire_resp ;
1068
1144
struct pf_vf_resc * resc = & resp -> resc ;
1069
1145
u8 status = bnx2x_pfvf_status_codes (vfop_status );
1146
+ u16 length ;
1070
1147
1071
1148
memset (resp , 0 , sizeof (* resp ));
1072
1149
@@ -1140,9 +1217,24 @@ static void bnx2x_vf_mbx_acquire_resp(struct bnx2x *bp, struct bnx2x_virtf *vf,
1140
1217
resc -> hw_sbs [i ].sb_qid );
1141
1218
DP_CONT (BNX2X_MSG_IOV , "]\n" );
1142
1219
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
+
1143
1235
/* send the response */
1144
1236
vf -> op_rc = vfop_status ;
1145
- bnx2x_vf_mbx_resp (bp , vf );
1237
+ bnx2x_vf_mbx_resp_send_msg (bp , vf );
1146
1238
}
1147
1239
1148
1240
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)
1874
1966
/* process the VF message header */
1875
1967
mbx -> first_tlv = mbx -> msg -> req .first_tlv ;
1876
1968
1969
+ /* Clean response buffer to refrain from falsely seeing chains */
1970
+ memset (& mbx -> msg -> resp , 0 , sizeof (union pfvf_tlvs ));
1971
+
1877
1972
/* dispatch the request (will prepare the response) */
1878
1973
bnx2x_vf_mbx_request (bp , vf , mbx );
1879
1974
goto mbx_done ;
0 commit comments