@@ -55,14 +55,101 @@ static u32 rvu_get_lmtst_tbl_index(struct rvu *rvu, u16 pcifunc)
55
55
(pcifunc & RVU_PFVF_FUNC_MASK )) * LMT_MAPTBL_ENTRY_SIZE ;
56
56
}
57
57
58
+ static int rvu_get_lmtaddr (struct rvu * rvu , u16 pcifunc ,
59
+ u64 iova , u64 * lmt_addr )
60
+ {
61
+ u64 pa , val , pf ;
62
+ int err ;
63
+
64
+ if (!iova ) {
65
+ dev_err (rvu -> dev , "%s Requested Null address for transulation\n" , __func__ );
66
+ return - EINVAL ;
67
+ }
68
+
69
+ rvu_write64 (rvu , BLKADDR_RVUM , RVU_AF_SMMU_ADDR_REQ , iova );
70
+ pf = rvu_get_pf (pcifunc ) & 0x1F ;
71
+ val = BIT_ULL (63 ) | BIT_ULL (14 ) | BIT_ULL (13 ) | pf << 8 |
72
+ ((pcifunc & RVU_PFVF_FUNC_MASK ) & 0xFF );
73
+ rvu_write64 (rvu , BLKADDR_RVUM , RVU_AF_SMMU_TXN_REQ , val );
74
+
75
+ err = rvu_poll_reg (rvu , BLKADDR_RVUM , RVU_AF_SMMU_ADDR_RSP_STS , BIT_ULL (0 ), false);
76
+ if (err ) {
77
+ dev_err (rvu -> dev , "%s LMTLINE iova transulation failed\n" , __func__ );
78
+ return err ;
79
+ }
80
+ val = rvu_read64 (rvu , BLKADDR_RVUM , RVU_AF_SMMU_ADDR_RSP_STS );
81
+ if (val & ~0x1ULL ) {
82
+ dev_err (rvu -> dev , "%s LMTLINE iova transulation failed err:%llx\n" , __func__ , val );
83
+ return - EIO ;
84
+ }
85
+ /* PA[51:12] = RVU_AF_SMMU_TLN_FLIT1[60:21]
86
+ * PA[11:0] = IOVA[11:0]
87
+ */
88
+ pa = rvu_read64 (rvu , BLKADDR_RVUM , RVU_AF_SMMU_TLN_FLIT1 ) >> 21 ;
89
+ pa &= GENMASK_ULL (39 , 0 );
90
+ * lmt_addr = (pa << 12 ) | (iova & 0xFFF );
91
+
92
+ return 0 ;
93
+ }
94
+
95
+ static int rvu_update_lmtaddr (struct rvu * rvu , u16 pcifunc , u64 lmt_addr )
96
+ {
97
+ struct rvu_pfvf * pfvf = rvu_get_pfvf (rvu , pcifunc );
98
+ u32 tbl_idx ;
99
+ int err = 0 ;
100
+ u64 val ;
101
+
102
+ /* Read the current lmt addr of pcifunc */
103
+ tbl_idx = rvu_get_lmtst_tbl_index (rvu , pcifunc );
104
+ err = lmtst_map_table_ops (rvu , tbl_idx , & val , LMT_TBL_OP_READ );
105
+ if (err ) {
106
+ dev_err (rvu -> dev ,
107
+ "Failed to read LMT map table: index 0x%x err %d\n" ,
108
+ tbl_idx , err );
109
+ return err ;
110
+ }
111
+
112
+ /* Storing the seondary's lmt base address as this needs to be
113
+ * reverted in FLR. Also making sure this default value doesn't
114
+ * get overwritten on multiple calls to this mailbox.
115
+ */
116
+ if (!pfvf -> lmt_base_addr )
117
+ pfvf -> lmt_base_addr = val ;
118
+
119
+ /* Update the LMT table with new addr */
120
+ err = lmtst_map_table_ops (rvu , tbl_idx , & lmt_addr , LMT_TBL_OP_WRITE );
121
+ if (err ) {
122
+ dev_err (rvu -> dev ,
123
+ "Failed to update LMT map table: index 0x%x err %d\n" ,
124
+ tbl_idx , err );
125
+ return err ;
126
+ }
127
+ return 0 ;
128
+ }
129
+
58
130
int rvu_mbox_handler_lmtst_tbl_setup (struct rvu * rvu ,
59
131
struct lmtst_tbl_setup_req * req ,
60
132
struct msg_rsp * rsp )
61
133
{
62
- struct rvu_pfvf * pfvf = rvu_get_pfvf ( rvu , req -> hdr . pcifunc ) ;
63
- u32 pri_tbl_idx , sec_tbl_idx ;
134
+ u64 lmt_addr , val ;
135
+ u32 pri_tbl_idx ;
64
136
int err = 0 ;
65
- u64 val ;
137
+
138
+ /* Check if PF_FUNC wants to use it's own local memory as LMTLINE
139
+ * region, if so, convert that IOVA to physical address and
140
+ * populate LMT table with that address
141
+ */
142
+ if (req -> use_local_lmt_region ) {
143
+ err = rvu_get_lmtaddr (rvu , req -> hdr .pcifunc ,
144
+ req -> lmt_iova , & lmt_addr );
145
+ if (err < 0 )
146
+ return err ;
147
+
148
+ /* Update the lmt addr for this PFFUNC in the LMT table */
149
+ err = rvu_update_lmtaddr (rvu , req -> hdr .pcifunc , lmt_addr );
150
+ if (err )
151
+ return err ;
152
+ }
66
153
67
154
/* Reconfiguring lmtst map table in lmt region shared mode i.e. make
68
155
* multiple PF_FUNCs to share an LMTLINE region, so primary/base
@@ -76,52 +163,25 @@ int rvu_mbox_handler_lmtst_tbl_setup(struct rvu *rvu,
76
163
*/
77
164
pri_tbl_idx = rvu_get_lmtst_tbl_index (rvu , req -> base_pcifunc );
78
165
79
- /* Truncating secondary pcifunc to calculate the LMT table index
80
- * equivalent to secondary pcifunc.
81
- */
82
- sec_tbl_idx = rvu_get_lmtst_tbl_index (rvu , req -> hdr .pcifunc );
83
- /* Read the base lmt addr of the secondary pcifunc */
84
- err = lmtst_map_table_ops (rvu , sec_tbl_idx , & val ,
85
- LMT_TBL_OP_READ );
86
- if (err ) {
87
- dev_err (rvu -> dev ,
88
- "Failed to read LMT map table: index 0x%x err %d\n" ,
89
- sec_tbl_idx , err );
90
- goto error ;
91
- }
92
-
93
- /* Storing the seondary's lmt base address as this needs to be
94
- * reverted in FLR. Also making sure this default value doesn't
95
- * get overwritten on multiple calls to this mailbox.
96
- */
97
- if (!pfvf -> lmt_base_addr )
98
- pfvf -> lmt_base_addr = val ;
99
-
100
166
/* Read the base lmt addr of the primary pcifunc */
101
167
err = lmtst_map_table_ops (rvu , pri_tbl_idx , & val ,
102
168
LMT_TBL_OP_READ );
103
169
if (err ) {
104
170
dev_err (rvu -> dev ,
105
171
"Failed to read LMT map table: index 0x%x err %d\n" ,
106
172
pri_tbl_idx , err );
107
- goto error ;
173
+ return err ;
108
174
}
109
175
110
176
/* Update the base lmt addr of secondary with primary's base
111
177
* lmt addr.
112
178
*/
113
- err = lmtst_map_table_ops (rvu , sec_tbl_idx , & val ,
114
- LMT_TBL_OP_WRITE );
115
- if (err ) {
116
- dev_err (rvu -> dev ,
117
- "Failed to update LMT map table: index 0x%x err %d\n" ,
118
- sec_tbl_idx , err );
119
- goto error ;
120
- }
179
+ err = rvu_update_lmtaddr (rvu , req -> hdr .pcifunc , val );
180
+ if (err )
181
+ return err ;
121
182
}
122
183
123
- error :
124
- return err ;
184
+ return 0 ;
125
185
}
126
186
127
187
/* Resetting the lmtst map table to original base addresses */
0 commit comments