@@ -2105,3 +2105,294 @@ int ixgbe_aci_get_netlist_node(struct ixgbe_hw *hw,
2105
2105
2106
2106
return 0 ;
2107
2107
}
2108
+
2109
+ /**
2110
+ * ixgbe_acquire_nvm - Generic request for acquiring the NVM ownership
2111
+ * @hw: pointer to the HW structure
2112
+ * @access: NVM access type (read or write)
2113
+ *
2114
+ * Request NVM ownership.
2115
+ *
2116
+ * Return: the exit code of the operation.
2117
+ */
2118
+ int ixgbe_acquire_nvm (struct ixgbe_hw * hw ,
2119
+ enum ixgbe_aci_res_access_type access )
2120
+ {
2121
+ u32 fla ;
2122
+
2123
+ /* Skip if we are in blank NVM programming mode */
2124
+ fla = IXGBE_READ_REG (hw , IXGBE_GLNVM_FLA );
2125
+ if ((fla & IXGBE_GLNVM_FLA_LOCKED_M ) == 0 )
2126
+ return 0 ;
2127
+
2128
+ return ixgbe_acquire_res (hw , IXGBE_NVM_RES_ID , access ,
2129
+ IXGBE_NVM_TIMEOUT );
2130
+ }
2131
+
2132
+ /**
2133
+ * ixgbe_release_nvm - Generic request for releasing the NVM ownership
2134
+ * @hw: pointer to the HW structure
2135
+ *
2136
+ * Release NVM ownership.
2137
+ */
2138
+ void ixgbe_release_nvm (struct ixgbe_hw * hw )
2139
+ {
2140
+ u32 fla ;
2141
+
2142
+ /* Skip if we are in blank NVM programming mode */
2143
+ fla = IXGBE_READ_REG (hw , IXGBE_GLNVM_FLA );
2144
+ if ((fla & IXGBE_GLNVM_FLA_LOCKED_M ) == 0 )
2145
+ return ;
2146
+
2147
+ ixgbe_release_res (hw , IXGBE_NVM_RES_ID );
2148
+ }
2149
+
2150
+ /**
2151
+ * ixgbe_aci_read_nvm - read NVM
2152
+ * @hw: pointer to the HW struct
2153
+ * @module_typeid: module pointer location in words from the NVM beginning
2154
+ * @offset: byte offset from the module beginning
2155
+ * @length: length of the section to be read (in bytes from the offset)
2156
+ * @data: command buffer (size [bytes] = length)
2157
+ * @last_command: tells if this is the last command in a series
2158
+ * @read_shadow_ram: tell if this is a shadow RAM read
2159
+ *
2160
+ * Read the NVM using ACI command (0x0701).
2161
+ *
2162
+ * Return: the exit code of the operation.
2163
+ */
2164
+ int ixgbe_aci_read_nvm (struct ixgbe_hw * hw , u16 module_typeid , u32 offset ,
2165
+ u16 length , void * data , bool last_command ,
2166
+ bool read_shadow_ram )
2167
+ {
2168
+ struct ixgbe_aci_cmd_nvm * cmd ;
2169
+ struct ixgbe_aci_desc desc ;
2170
+
2171
+ if (offset > IXGBE_ACI_NVM_MAX_OFFSET )
2172
+ return - EINVAL ;
2173
+
2174
+ cmd = & desc .params .nvm ;
2175
+
2176
+ ixgbe_fill_dflt_direct_cmd_desc (& desc , ixgbe_aci_opc_nvm_read );
2177
+
2178
+ if (!read_shadow_ram && module_typeid == IXGBE_ACI_NVM_START_POINT )
2179
+ cmd -> cmd_flags |= IXGBE_ACI_NVM_FLASH_ONLY ;
2180
+
2181
+ /* If this is the last command in a series, set the proper flag. */
2182
+ if (last_command )
2183
+ cmd -> cmd_flags |= IXGBE_ACI_NVM_LAST_CMD ;
2184
+ cmd -> module_typeid = cpu_to_le16 (module_typeid );
2185
+ cmd -> offset_low = cpu_to_le16 (offset & 0xFFFF );
2186
+ cmd -> offset_high = (offset >> 16 ) & 0xFF ;
2187
+ cmd -> length = cpu_to_le16 (length );
2188
+
2189
+ return ixgbe_aci_send_cmd (hw , & desc , data , length );
2190
+ }
2191
+
2192
+ /**
2193
+ * ixgbe_nvm_validate_checksum - validate checksum
2194
+ * @hw: pointer to the HW struct
2195
+ *
2196
+ * Verify NVM PFA checksum validity using ACI command (0x0706).
2197
+ * If the checksum verification failed, IXGBE_ERR_NVM_CHECKSUM is returned.
2198
+ * The function acquires and then releases the NVM ownership.
2199
+ *
2200
+ * Return: the exit code of the operation.
2201
+ */
2202
+ int ixgbe_nvm_validate_checksum (struct ixgbe_hw * hw )
2203
+ {
2204
+ struct ixgbe_aci_cmd_nvm_checksum * cmd ;
2205
+ struct ixgbe_aci_desc desc ;
2206
+ int err ;
2207
+
2208
+ err = ixgbe_acquire_nvm (hw , IXGBE_RES_READ );
2209
+ if (err )
2210
+ return err ;
2211
+
2212
+ cmd = & desc .params .nvm_checksum ;
2213
+
2214
+ ixgbe_fill_dflt_direct_cmd_desc (& desc , ixgbe_aci_opc_nvm_checksum );
2215
+ cmd -> flags = IXGBE_ACI_NVM_CHECKSUM_VERIFY ;
2216
+
2217
+ err = ixgbe_aci_send_cmd (hw , & desc , NULL , 0 );
2218
+
2219
+ ixgbe_release_nvm (hw );
2220
+
2221
+ if (!err && cmd -> checksum !=
2222
+ cpu_to_le16 (IXGBE_ACI_NVM_CHECKSUM_CORRECT )) {
2223
+ struct ixgbe_adapter * adapter = container_of (hw , struct ixgbe_adapter ,
2224
+ hw );
2225
+
2226
+ err = - EIO ;
2227
+ netdev_err (adapter -> netdev , "Invalid Shadow Ram checksum" );
2228
+ }
2229
+
2230
+ return err ;
2231
+ }
2232
+
2233
+ /**
2234
+ * ixgbe_read_sr_word_aci - Reads Shadow RAM via ACI
2235
+ * @hw: pointer to the HW structure
2236
+ * @offset: offset of the Shadow RAM word to read (0x000000 - 0x001FFF)
2237
+ * @data: word read from the Shadow RAM
2238
+ *
2239
+ * Reads one 16 bit word from the Shadow RAM using ixgbe_read_flat_nvm.
2240
+ *
2241
+ * Return: the exit code of the operation.
2242
+ */
2243
+ int ixgbe_read_sr_word_aci (struct ixgbe_hw * hw , u16 offset , u16 * data )
2244
+ {
2245
+ u32 bytes = sizeof (u16 );
2246
+ u16 data_local ;
2247
+ int err ;
2248
+
2249
+ err = ixgbe_read_flat_nvm (hw , offset * sizeof (u16 ), & bytes ,
2250
+ (u8 * )& data_local , true);
2251
+ if (err )
2252
+ return err ;
2253
+
2254
+ * data = data_local ;
2255
+ return 0 ;
2256
+ }
2257
+
2258
+ /**
2259
+ * ixgbe_read_flat_nvm - Read portion of NVM by flat offset
2260
+ * @hw: pointer to the HW struct
2261
+ * @offset: offset from beginning of NVM
2262
+ * @length: (in) number of bytes to read; (out) number of bytes actually read
2263
+ * @data: buffer to return data in (sized to fit the specified length)
2264
+ * @read_shadow_ram: if true, read from shadow RAM instead of NVM
2265
+ *
2266
+ * Reads a portion of the NVM, as a flat memory space. This function correctly
2267
+ * breaks read requests across Shadow RAM sectors, prevents Shadow RAM size
2268
+ * from being exceeded in case of Shadow RAM read requests and ensures that no
2269
+ * single read request exceeds the maximum 4KB read for a single admin command.
2270
+ *
2271
+ * Returns an error code on failure. Note that the data pointer may be
2272
+ * partially updated if some reads succeed before a failure.
2273
+ *
2274
+ * Return: the exit code of the operation.
2275
+ */
2276
+ int ixgbe_read_flat_nvm (struct ixgbe_hw * hw , u32 offset , u32 * length ,
2277
+ u8 * data , bool read_shadow_ram )
2278
+ {
2279
+ u32 inlen = * length ;
2280
+ u32 bytes_read = 0 ;
2281
+ bool last_cmd ;
2282
+ int err ;
2283
+
2284
+ /* Verify the length of the read if this is for the Shadow RAM */
2285
+ if (read_shadow_ram && ((offset + inlen ) >
2286
+ (hw -> eeprom .word_size * 2u )))
2287
+ return - EINVAL ;
2288
+
2289
+ do {
2290
+ u32 read_size , sector_offset ;
2291
+
2292
+ /* ixgbe_aci_read_nvm cannot read more than 4KB at a time.
2293
+ * Additionally, a read from the Shadow RAM may not cross over
2294
+ * a sector boundary. Conveniently, the sector size is also 4KB.
2295
+ */
2296
+ sector_offset = offset % IXGBE_ACI_MAX_BUFFER_SIZE ;
2297
+ read_size = min_t (u32 ,
2298
+ IXGBE_ACI_MAX_BUFFER_SIZE - sector_offset ,
2299
+ inlen - bytes_read );
2300
+
2301
+ last_cmd = !(bytes_read + read_size < inlen );
2302
+
2303
+ /* ixgbe_aci_read_nvm takes the length as a u16. Our read_size
2304
+ * is calculated using a u32, but the IXGBE_ACI_MAX_BUFFER_SIZE
2305
+ * maximum size guarantees that it will fit within the 2 bytes.
2306
+ */
2307
+ err = ixgbe_aci_read_nvm (hw , IXGBE_ACI_NVM_START_POINT ,
2308
+ offset , (u16 )read_size ,
2309
+ data + bytes_read , last_cmd ,
2310
+ read_shadow_ram );
2311
+ if (err )
2312
+ break ;
2313
+
2314
+ bytes_read += read_size ;
2315
+ offset += read_size ;
2316
+ } while (!last_cmd );
2317
+
2318
+ * length = bytes_read ;
2319
+ return err ;
2320
+ }
2321
+
2322
+ /**
2323
+ * ixgbe_read_ee_aci_e610 - Read EEPROM word using the admin command.
2324
+ * @hw: pointer to hardware structure
2325
+ * @offset: offset of word in the EEPROM to read
2326
+ * @data: word read from the EEPROM
2327
+ *
2328
+ * Reads a 16 bit word from the EEPROM using the ACI.
2329
+ * If the EEPROM params are not initialized, the function
2330
+ * initialize them before proceeding with reading.
2331
+ * The function acquires and then releases the NVM ownership.
2332
+ *
2333
+ * Return: the exit code of the operation.
2334
+ */
2335
+ int ixgbe_read_ee_aci_e610 (struct ixgbe_hw * hw , u16 offset , u16 * data )
2336
+ {
2337
+ int err ;
2338
+
2339
+ if (hw -> eeprom .type == ixgbe_eeprom_uninitialized ) {
2340
+ err = hw -> eeprom .ops .init_params (hw );
2341
+ if (err )
2342
+ return err ;
2343
+ }
2344
+
2345
+ err = ixgbe_acquire_nvm (hw , IXGBE_RES_READ );
2346
+ if (err )
2347
+ return err ;
2348
+
2349
+ err = ixgbe_read_sr_word_aci (hw , offset , data );
2350
+ ixgbe_release_nvm (hw );
2351
+
2352
+ return err ;
2353
+ }
2354
+
2355
+ /**
2356
+ * ixgbe_validate_eeprom_checksum_e610 - Validate EEPROM checksum
2357
+ * @hw: pointer to hardware structure
2358
+ * @checksum_val: calculated checksum
2359
+ *
2360
+ * Performs checksum calculation and validates the EEPROM checksum. If the
2361
+ * caller does not need checksum_val, the value can be NULL.
2362
+ * If the EEPROM params are not initialized, the function
2363
+ * initialize them before proceeding.
2364
+ * The function acquires and then releases the NVM ownership.
2365
+ *
2366
+ * Return: the exit code of the operation.
2367
+ */
2368
+ int ixgbe_validate_eeprom_checksum_e610 (struct ixgbe_hw * hw , u16 * checksum_val )
2369
+ {
2370
+ int err ;
2371
+
2372
+ if (hw -> eeprom .type == ixgbe_eeprom_uninitialized ) {
2373
+ err = hw -> eeprom .ops .init_params (hw );
2374
+ if (err )
2375
+ return err ;
2376
+ }
2377
+
2378
+ err = ixgbe_nvm_validate_checksum (hw );
2379
+ if (err )
2380
+ return err ;
2381
+
2382
+ if (checksum_val ) {
2383
+ u16 tmp_checksum ;
2384
+
2385
+ err = ixgbe_acquire_nvm (hw , IXGBE_RES_READ );
2386
+ if (err )
2387
+ return err ;
2388
+
2389
+ err = ixgbe_read_sr_word_aci (hw , E610_SR_SW_CHECKSUM_WORD ,
2390
+ & tmp_checksum );
2391
+ ixgbe_release_nvm (hw );
2392
+
2393
+ if (!err )
2394
+ * checksum_val = tmp_checksum ;
2395
+ }
2396
+
2397
+ return err ;
2398
+ }
0 commit comments