@@ -574,6 +574,15 @@ static int reset_tx_pools(struct ibmvnic_adapter *adapter)
574
574
return 0 ;
575
575
}
576
576
577
+ static void release_vpd_data (struct ibmvnic_adapter * adapter )
578
+ {
579
+ if (!adapter -> vpd )
580
+ return ;
581
+
582
+ kfree (adapter -> vpd -> buff );
583
+ kfree (adapter -> vpd );
584
+ }
585
+
577
586
static void release_tx_pools (struct ibmvnic_adapter * adapter )
578
587
{
579
588
struct ibmvnic_tx_pool * tx_pool ;
@@ -754,6 +763,8 @@ static void release_resources(struct ibmvnic_adapter *adapter)
754
763
{
755
764
int i ;
756
765
766
+ release_vpd_data (adapter );
767
+
757
768
release_tx_pools (adapter );
758
769
release_rx_pools (adapter );
759
770
@@ -834,6 +845,57 @@ static int set_real_num_queues(struct net_device *netdev)
834
845
return rc ;
835
846
}
836
847
848
+ static int ibmvnic_get_vpd (struct ibmvnic_adapter * adapter )
849
+ {
850
+ struct device * dev = & adapter -> vdev -> dev ;
851
+ union ibmvnic_crq crq ;
852
+ dma_addr_t dma_addr ;
853
+ int len = 0 ;
854
+
855
+ if (adapter -> vpd -> buff )
856
+ len = adapter -> vpd -> len ;
857
+
858
+ reinit_completion (& adapter -> fw_done );
859
+ crq .get_vpd_size .first = IBMVNIC_CRQ_CMD ;
860
+ crq .get_vpd_size .cmd = GET_VPD_SIZE ;
861
+ ibmvnic_send_crq (adapter , & crq );
862
+ wait_for_completion (& adapter -> fw_done );
863
+
864
+ if (!adapter -> vpd -> len )
865
+ return - ENODATA ;
866
+
867
+ if (!adapter -> vpd -> buff )
868
+ adapter -> vpd -> buff = kzalloc (adapter -> vpd -> len , GFP_KERNEL );
869
+ else if (adapter -> vpd -> len != len )
870
+ adapter -> vpd -> buff =
871
+ krealloc (adapter -> vpd -> buff ,
872
+ adapter -> vpd -> len , GFP_KERNEL );
873
+
874
+ if (!adapter -> vpd -> buff ) {
875
+ dev_err (dev , "Could allocate VPD buffer\n" );
876
+ return - ENOMEM ;
877
+ }
878
+
879
+ adapter -> vpd -> dma_addr =
880
+ dma_map_single (dev , adapter -> vpd -> buff , adapter -> vpd -> len ,
881
+ DMA_FROM_DEVICE );
882
+ if (dma_mapping_error (dev , dma_addr )) {
883
+ dev_err (dev , "Could not map VPD buffer\n" );
884
+ kfree (adapter -> vpd -> buff );
885
+ return - ENOMEM ;
886
+ }
887
+
888
+ reinit_completion (& adapter -> fw_done );
889
+ crq .get_vpd .first = IBMVNIC_CRQ_CMD ;
890
+ crq .get_vpd .cmd = GET_VPD ;
891
+ crq .get_vpd .ioba = cpu_to_be32 (adapter -> vpd -> dma_addr );
892
+ crq .get_vpd .len = cpu_to_be32 ((u32 )adapter -> vpd -> len );
893
+ ibmvnic_send_crq (adapter , & crq );
894
+ wait_for_completion (& adapter -> fw_done );
895
+
896
+ return 0 ;
897
+ }
898
+
837
899
static int init_resources (struct ibmvnic_adapter * adapter )
838
900
{
839
901
struct net_device * netdev = adapter -> netdev ;
@@ -851,6 +913,10 @@ static int init_resources(struct ibmvnic_adapter *adapter)
851
913
if (rc )
852
914
return rc ;
853
915
916
+ adapter -> vpd = kzalloc (sizeof (* adapter -> vpd ), GFP_KERNEL );
917
+ if (!adapter -> vpd )
918
+ return - ENOMEM ;
919
+
854
920
adapter -> map_id = 1 ;
855
921
adapter -> napi = kcalloc (adapter -> req_rx_queues ,
856
922
sizeof (struct napi_struct ), GFP_KERNEL );
@@ -924,7 +990,7 @@ static int __ibmvnic_open(struct net_device *netdev)
924
990
static int ibmvnic_open (struct net_device * netdev )
925
991
{
926
992
struct ibmvnic_adapter * adapter = netdev_priv (netdev );
927
- int rc ;
993
+ int rc , vpd ;
928
994
929
995
mutex_lock (& adapter -> reset_lock );
930
996
@@ -951,6 +1017,12 @@ static int ibmvnic_open(struct net_device *netdev)
951
1017
952
1018
rc = __ibmvnic_open (netdev );
953
1019
netif_carrier_on (netdev );
1020
+
1021
+ /* Vital Product Data (VPD) */
1022
+ vpd = ibmvnic_get_vpd (adapter );
1023
+ if (vpd )
1024
+ netdev_err (netdev , "failed to initialize Vital Product Data (VPD)\n" );
1025
+
954
1026
mutex_unlock (& adapter -> reset_lock );
955
1027
956
1028
return rc ;
@@ -1879,11 +1951,15 @@ static int ibmvnic_get_link_ksettings(struct net_device *netdev,
1879
1951
return 0 ;
1880
1952
}
1881
1953
1882
- static void ibmvnic_get_drvinfo (struct net_device * dev ,
1954
+ static void ibmvnic_get_drvinfo (struct net_device * netdev ,
1883
1955
struct ethtool_drvinfo * info )
1884
1956
{
1957
+ struct ibmvnic_adapter * adapter = netdev_priv (netdev );
1958
+
1885
1959
strlcpy (info -> driver , ibmvnic_driver_name , sizeof (info -> driver ));
1886
1960
strlcpy (info -> version , IBMVNIC_DRIVER_VERSION , sizeof (info -> version ));
1961
+ strlcpy (info -> fw_version , adapter -> fw_version ,
1962
+ sizeof (info -> fw_version ));
1887
1963
}
1888
1964
1889
1965
static u32 ibmvnic_get_msglevel (struct net_device * netdev )
@@ -3140,6 +3216,73 @@ static void send_cap_queries(struct ibmvnic_adapter *adapter)
3140
3216
ibmvnic_send_crq (adapter , & crq );
3141
3217
}
3142
3218
3219
+ static void handle_vpd_size_rsp (union ibmvnic_crq * crq ,
3220
+ struct ibmvnic_adapter * adapter )
3221
+ {
3222
+ struct device * dev = & adapter -> vdev -> dev ;
3223
+
3224
+ if (crq -> get_vpd_size_rsp .rc .code ) {
3225
+ dev_err (dev , "Error retrieving VPD size, rc=%x\n" ,
3226
+ crq -> get_vpd_size_rsp .rc .code );
3227
+ complete (& adapter -> fw_done );
3228
+ return ;
3229
+ }
3230
+
3231
+ adapter -> vpd -> len = be64_to_cpu (crq -> get_vpd_size_rsp .len );
3232
+ complete (& adapter -> fw_done );
3233
+ }
3234
+
3235
+ static void handle_vpd_rsp (union ibmvnic_crq * crq ,
3236
+ struct ibmvnic_adapter * adapter )
3237
+ {
3238
+ struct device * dev = & adapter -> vdev -> dev ;
3239
+ unsigned char * substr = NULL , * ptr = NULL ;
3240
+ u8 fw_level_len = 0 ;
3241
+
3242
+ memset (adapter -> fw_version , 0 , 32 );
3243
+
3244
+ dma_unmap_single (dev , adapter -> vpd -> dma_addr , adapter -> vpd -> len ,
3245
+ DMA_FROM_DEVICE );
3246
+
3247
+ if (crq -> get_vpd_rsp .rc .code ) {
3248
+ dev_err (dev , "Error retrieving VPD from device, rc=%x\n" ,
3249
+ crq -> get_vpd_rsp .rc .code );
3250
+ goto complete ;
3251
+ }
3252
+
3253
+ /* get the position of the firmware version info
3254
+ * located after the ASCII 'RM' substring in the buffer
3255
+ */
3256
+ substr = strnstr (adapter -> vpd -> buff , "RM" , adapter -> vpd -> len );
3257
+ if (!substr ) {
3258
+ dev_info (dev , "No FW level provided by VPD\n" );
3259
+ goto complete ;
3260
+ }
3261
+
3262
+ /* get length of firmware level ASCII substring */
3263
+ if ((substr + 2 ) < (adapter -> vpd -> buff + adapter -> vpd -> len )) {
3264
+ fw_level_len = * (substr + 2 );
3265
+ } else {
3266
+ dev_info (dev , "Length of FW substr extrapolated VDP buff\n" );
3267
+ goto complete ;
3268
+ }
3269
+
3270
+ /* copy firmware version string from vpd into adapter */
3271
+ if ((substr + 3 + fw_level_len ) <
3272
+ (adapter -> vpd -> buff + adapter -> vpd -> len )) {
3273
+ ptr = strncpy ((char * )adapter -> fw_version ,
3274
+ substr + 3 , fw_level_len );
3275
+
3276
+ if (!ptr )
3277
+ dev_err (dev , "Failed to isolate FW level string\n" );
3278
+ } else {
3279
+ dev_info (dev , "FW substr extrapolated VPD buff\n" );
3280
+ }
3281
+
3282
+ complete :
3283
+ complete (& adapter -> fw_done );
3284
+ }
3285
+
3143
3286
static void handle_query_ip_offload_rsp (struct ibmvnic_adapter * adapter )
3144
3287
{
3145
3288
struct device * dev = & adapter -> vdev -> dev ;
@@ -3871,6 +4014,12 @@ static void ibmvnic_handle_crq(union ibmvnic_crq *crq,
3871
4014
netdev_dbg (netdev , "Got Collect firmware trace Response\n" );
3872
4015
complete (& adapter -> fw_done );
3873
4016
break ;
4017
+ case GET_VPD_SIZE_RSP :
4018
+ handle_vpd_size_rsp (crq , adapter );
4019
+ break ;
4020
+ case GET_VPD_RSP :
4021
+ handle_vpd_rsp (crq , adapter );
4022
+ break ;
3874
4023
default :
3875
4024
netdev_err (netdev , "Got an invalid cmd type 0x%02x\n" ,
3876
4025
gen_crq -> cmd );
0 commit comments