@@ -1396,6 +1396,167 @@ static void test_admin_ns_detach(struct nvme_mi_ep *ep)
13961396 assert (!rc );
13971397}
13981398
1399+ struct fw_download_info {
1400+ uint32_t offset ;
1401+ uint32_t len ;
1402+ void * data ;
1403+ };
1404+
1405+ static int test_admin_fw_download_cb (struct nvme_mi_ep * ep ,
1406+ struct nvme_mi_req * req ,
1407+ struct nvme_mi_resp * resp ,
1408+ void * data )
1409+ {
1410+ struct fw_download_info * info = data ;
1411+ __u32 len , off ;
1412+ __u8 * rq_hdr ;
1413+
1414+ rq_hdr = (__u8 * )req -> hdr ;
1415+ assert (rq_hdr [4 ] == nvme_admin_fw_download );
1416+
1417+ len = rq_hdr [47 ] << 24 | rq_hdr [46 ] << 16 | rq_hdr [45 ] << 8 | rq_hdr [44 ];
1418+ off = rq_hdr [51 ] << 24 | rq_hdr [50 ] << 16 | rq_hdr [49 ] << 8 | rq_hdr [48 ];
1419+
1420+ assert (off << 2 == info -> offset );
1421+ assert (((len + 1 ) << 2 ) == info -> len );
1422+
1423+ /* ensure that the request len matches too */
1424+ assert (req -> data_len == info -> len );
1425+
1426+ assert (!memcmp (req -> data , info -> data , len ));
1427+
1428+ test_transport_resp_calc_mic (resp );
1429+
1430+ return 0 ;
1431+ }
1432+
1433+ static void test_admin_fw_download (struct nvme_mi_ep * ep )
1434+ {
1435+ struct nvme_fw_download_args args ;
1436+ struct fw_download_info info ;
1437+ unsigned char fw [4096 ];
1438+ nvme_mi_ctrl_t ctrl ;
1439+ int rc , i ;
1440+
1441+ for (i = 0 ; i < sizeof (fw ); i ++ )
1442+ fw [i ] = i % 0xff ;
1443+
1444+ info .offset = 0 ;
1445+ info .len = 0 ;
1446+ info .data = fw ;
1447+ args .data = fw ;
1448+ args .args_size = sizeof (args );
1449+
1450+ test_set_transport_callback (ep , test_admin_fw_download_cb , & info );
1451+
1452+ ctrl = nvme_mi_init_ctrl (ep , 5 );
1453+ assert (ctrl );
1454+
1455+ /* invalid (zero) len */
1456+ args .data_len = info .len = 1 ;
1457+ args .offset = info .offset = 0 ;
1458+ rc = nvme_mi_admin_fw_download (ctrl , & args );
1459+ assert (rc );
1460+
1461+ /* invalid (unaligned) len */
1462+ args .data_len = info .len = 1 ;
1463+ args .offset = info .offset = 0 ;
1464+ rc = nvme_mi_admin_fw_download (ctrl , & args );
1465+ assert (rc );
1466+
1467+ /* invalid offset */
1468+ args .data_len = info .len = 4 ;
1469+ args .offset = info .offset = 1 ;
1470+ rc = nvme_mi_admin_fw_download (ctrl , & args );
1471+ assert (rc );
1472+
1473+ /* smallest len */
1474+ args .data_len = info .len = 4 ;
1475+ args .offset = info .offset = 0 ;
1476+ rc = nvme_mi_admin_fw_download (ctrl , & args );
1477+ assert (!rc );
1478+
1479+ /* largest len */
1480+ args .data_len = info .len = 4096 ;
1481+ args .offset = info .offset = 0 ;
1482+ rc = nvme_mi_admin_fw_download (ctrl , & args );
1483+ assert (!rc );
1484+
1485+ /* offset value */
1486+ args .data_len = info .len = 4096 ;
1487+ args .offset = info .offset = 4096 ;
1488+ rc = nvme_mi_admin_fw_download (ctrl , & args );
1489+ assert (!rc );
1490+ }
1491+
1492+ struct fw_commit_info {
1493+ __u8 bpid ;
1494+ __u8 action ;
1495+ __u8 slot ;
1496+ };
1497+
1498+ static int test_admin_fw_commit_cb (struct nvme_mi_ep * ep ,
1499+ struct nvme_mi_req * req ,
1500+ struct nvme_mi_resp * resp ,
1501+ void * data )
1502+ {
1503+ struct fw_commit_info * info = data ;
1504+ __u8 bpid , action , slot ;
1505+ __u8 * rq_hdr ;
1506+
1507+ rq_hdr = (__u8 * )req -> hdr ;
1508+ assert (rq_hdr [4 ] == nvme_admin_fw_commit );
1509+
1510+ bpid = (rq_hdr [47 ] >> 7 ) & 0x1 ;
1511+ slot = rq_hdr [44 ] & 0x7 ;
1512+ action = (rq_hdr [44 ] >> 3 ) & 0x7 ;
1513+
1514+ assert (!!bpid == !!info -> bpid );
1515+ assert (slot == info -> slot );
1516+ assert (action == info -> action );
1517+
1518+ test_transport_resp_calc_mic (resp );
1519+
1520+ return 0 ;
1521+ }
1522+
1523+ static void test_admin_fw_commit (struct nvme_mi_ep * ep )
1524+ {
1525+ struct nvme_fw_commit_args args ;
1526+ struct fw_commit_info info ;
1527+ nvme_mi_ctrl_t ctrl ;
1528+ int rc ;
1529+
1530+ args .args_size = sizeof (args );
1531+ info .bpid = args .bpid = 0 ;
1532+
1533+ test_set_transport_callback (ep , test_admin_fw_commit_cb , & info );
1534+
1535+ ctrl = nvme_mi_init_ctrl (ep , 5 );
1536+ assert (ctrl );
1537+
1538+ /* all zeros */
1539+ info .bpid = args .bpid = 0 ;
1540+ info .slot = args .slot = 0 ;
1541+ info .action = args .action = 0 ;
1542+ rc = nvme_mi_admin_fw_commit (ctrl , & args );
1543+ assert (!rc );
1544+
1545+ /* all ones */
1546+ info .bpid = args .bpid = 1 ;
1547+ info .slot = args .slot = 0x7 ;
1548+ info .action = args .action = 0x7 ;
1549+ rc = nvme_mi_admin_fw_commit (ctrl , & args );
1550+ assert (!rc );
1551+
1552+ /* correct fields */
1553+ info .bpid = args .bpid = 1 ;
1554+ info .slot = args .slot = 2 ;
1555+ info .action = args .action = 3 ;
1556+ rc = nvme_mi_admin_fw_commit (ctrl , & args );
1557+ assert (!rc );
1558+ }
1559+
13991560struct format_data {
14001561 __u32 nsid ;
14011562 __u8 lbafu ;
@@ -1573,6 +1734,8 @@ struct test {
15731734 DEFINE_TEST (admin_ns_mgmt_delete ),
15741735 DEFINE_TEST (admin_ns_attach ),
15751736 DEFINE_TEST (admin_ns_detach ),
1737+ DEFINE_TEST (admin_fw_download ),
1738+ DEFINE_TEST (admin_fw_commit ),
15761739 DEFINE_TEST (admin_format_nvm ),
15771740 DEFINE_TEST (admin_sanitize_nvm ),
15781741};
0 commit comments