@@ -4602,6 +4602,42 @@ int qeth_query_oat_command(struct qeth_card *card, char __user *udata)
4602
4602
}
4603
4603
EXPORT_SYMBOL_GPL (qeth_query_oat_command );
4604
4604
4605
+ int qeth_query_card_info_cb (struct qeth_card * card ,
4606
+ struct qeth_reply * reply , unsigned long data )
4607
+ {
4608
+ struct qeth_ipa_cmd * cmd ;
4609
+ struct qeth_query_card_info * card_info ;
4610
+ struct carrier_info * carrier_info ;
4611
+
4612
+ QETH_CARD_TEXT (card , 2 , "qcrdincb" );
4613
+ carrier_info = (struct carrier_info * )reply -> param ;
4614
+ cmd = (struct qeth_ipa_cmd * )data ;
4615
+ card_info = & cmd -> data .setadapterparms .data .card_info ;
4616
+ if (cmd -> data .setadapterparms .hdr .return_code == 0 ) {
4617
+ carrier_info -> card_type = card_info -> card_type ;
4618
+ carrier_info -> port_mode = card_info -> port_mode ;
4619
+ carrier_info -> port_speed = card_info -> port_speed ;
4620
+ }
4621
+
4622
+ qeth_default_setadapterparms_cb (card , reply , (unsigned long ) cmd );
4623
+ return 0 ;
4624
+ }
4625
+
4626
+ int qeth_query_card_info (struct qeth_card * card ,
4627
+ struct carrier_info * carrier_info )
4628
+ {
4629
+ struct qeth_cmd_buffer * iob ;
4630
+
4631
+ QETH_CARD_TEXT (card , 2 , "qcrdinfo" );
4632
+ if (!qeth_adp_supported (card , IPA_SETADP_QUERY_CARD_INFO ))
4633
+ return - EOPNOTSUPP ;
4634
+ iob = qeth_get_adapter_cmd (card , IPA_SETADP_QUERY_CARD_INFO ,
4635
+ sizeof (struct qeth_ipacmd_setadpparms_hdr ));
4636
+ return qeth_send_ipa_cmd (card , iob , qeth_query_card_info_cb ,
4637
+ (void * )carrier_info );
4638
+ }
4639
+ EXPORT_SYMBOL_GPL (qeth_query_card_info );
4640
+
4605
4641
static inline int qeth_get_qdio_q_format (struct qeth_card * card )
4606
4642
{
4607
4643
switch (card -> info .type ) {
@@ -5606,92 +5642,158 @@ void qeth_core_get_drvinfo(struct net_device *dev,
5606
5642
}
5607
5643
EXPORT_SYMBOL_GPL (qeth_core_get_drvinfo );
5608
5644
5645
+ /* Helper function to fill 'advertizing' and 'supported' which are the same. */
5646
+ /* Autoneg and full-duplex are supported and advertized uncondionally. */
5647
+ /* Always advertize and support all speeds up to specified, and only one */
5648
+ /* specified port type. */
5649
+ static void qeth_set_ecmd_adv_sup (struct ethtool_cmd * ecmd ,
5650
+ int maxspeed , int porttype )
5651
+ {
5652
+ int port_sup , port_adv , spd_sup , spd_adv ;
5653
+
5654
+ switch (porttype ) {
5655
+ case PORT_TP :
5656
+ port_sup = SUPPORTED_TP ;
5657
+ port_adv = ADVERTISED_TP ;
5658
+ break ;
5659
+ case PORT_FIBRE :
5660
+ port_sup = SUPPORTED_FIBRE ;
5661
+ port_adv = ADVERTISED_FIBRE ;
5662
+ break ;
5663
+ default :
5664
+ port_sup = SUPPORTED_TP ;
5665
+ port_adv = ADVERTISED_TP ;
5666
+ WARN_ON_ONCE (1 );
5667
+ }
5668
+
5669
+ /* "Fallthrough" case'es ordered from high to low result in setting */
5670
+ /* flags cumulatively, starting from the specified speed and down to */
5671
+ /* the lowest possible. */
5672
+ spd_sup = 0 ;
5673
+ spd_adv = 0 ;
5674
+ switch (maxspeed ) {
5675
+ case SPEED_10000 :
5676
+ spd_sup |= SUPPORTED_10000baseT_Full ;
5677
+ spd_adv |= ADVERTISED_10000baseT_Full ;
5678
+ case SPEED_1000 :
5679
+ spd_sup |= SUPPORTED_1000baseT_Half | SUPPORTED_1000baseT_Full ;
5680
+ spd_adv |= ADVERTISED_1000baseT_Half |
5681
+ ADVERTISED_1000baseT_Full ;
5682
+ case SPEED_100 :
5683
+ spd_sup |= SUPPORTED_100baseT_Half | SUPPORTED_100baseT_Full ;
5684
+ spd_adv |= ADVERTISED_100baseT_Half | ADVERTISED_100baseT_Full ;
5685
+ case SPEED_10 :
5686
+ spd_sup |= SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full ;
5687
+ spd_adv |= ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full ;
5688
+ break ;
5689
+ default :
5690
+ spd_sup = SUPPORTED_10baseT_Half | SUPPORTED_10baseT_Full ;
5691
+ spd_adv = ADVERTISED_10baseT_Half | ADVERTISED_10baseT_Full ;
5692
+ WARN_ON_ONCE (1 );
5693
+ }
5694
+ ecmd -> advertising = ADVERTISED_Autoneg | port_adv | spd_adv ;
5695
+ ecmd -> supported = SUPPORTED_Autoneg | port_sup | spd_sup ;
5696
+ }
5697
+
5609
5698
int qeth_core_ethtool_get_settings (struct net_device * netdev ,
5610
5699
struct ethtool_cmd * ecmd )
5611
5700
{
5612
5701
struct qeth_card * card = netdev -> ml_priv ;
5613
5702
enum qeth_link_types link_type ;
5703
+ struct carrier_info carrier_info ;
5614
5704
5615
5705
if ((card -> info .type == QETH_CARD_TYPE_IQD ) || (card -> info .guestlan ))
5616
5706
link_type = QETH_LINK_TYPE_10GBIT_ETH ;
5617
5707
else
5618
5708
link_type = card -> info .link_type ;
5619
5709
5620
5710
ecmd -> transceiver = XCVR_INTERNAL ;
5621
- ecmd -> supported = SUPPORTED_Autoneg ;
5622
- ecmd -> advertising = ADVERTISED_Autoneg ;
5623
5711
ecmd -> duplex = DUPLEX_FULL ;
5624
5712
ecmd -> autoneg = AUTONEG_ENABLE ;
5625
5713
5626
5714
switch (link_type ) {
5627
5715
case QETH_LINK_TYPE_FAST_ETH :
5628
5716
case QETH_LINK_TYPE_LANE_ETH100 :
5629
- ecmd -> supported |= SUPPORTED_10baseT_Half |
5630
- SUPPORTED_10baseT_Full |
5631
- SUPPORTED_100baseT_Half |
5632
- SUPPORTED_100baseT_Full |
5633
- SUPPORTED_TP ;
5634
- ecmd -> advertising |= ADVERTISED_10baseT_Half |
5635
- ADVERTISED_10baseT_Full |
5636
- ADVERTISED_100baseT_Half |
5637
- ADVERTISED_100baseT_Full |
5638
- ADVERTISED_TP ;
5717
+ qeth_set_ecmd_adv_sup (ecmd , SPEED_100 , PORT_TP );
5639
5718
ecmd -> speed = SPEED_100 ;
5640
5719
ecmd -> port = PORT_TP ;
5641
5720
break ;
5642
5721
5643
5722
case QETH_LINK_TYPE_GBIT_ETH :
5644
5723
case QETH_LINK_TYPE_LANE_ETH1000 :
5645
- ecmd -> supported |= SUPPORTED_10baseT_Half |
5646
- SUPPORTED_10baseT_Full |
5647
- SUPPORTED_100baseT_Half |
5648
- SUPPORTED_100baseT_Full |
5649
- SUPPORTED_1000baseT_Half |
5650
- SUPPORTED_1000baseT_Full |
5651
- SUPPORTED_FIBRE ;
5652
- ecmd -> advertising |= ADVERTISED_10baseT_Half |
5653
- ADVERTISED_10baseT_Full |
5654
- ADVERTISED_100baseT_Half |
5655
- ADVERTISED_100baseT_Full |
5656
- ADVERTISED_1000baseT_Half |
5657
- ADVERTISED_1000baseT_Full |
5658
- ADVERTISED_FIBRE ;
5724
+ qeth_set_ecmd_adv_sup (ecmd , SPEED_1000 , PORT_FIBRE );
5659
5725
ecmd -> speed = SPEED_1000 ;
5660
5726
ecmd -> port = PORT_FIBRE ;
5661
5727
break ;
5662
5728
5663
5729
case QETH_LINK_TYPE_10GBIT_ETH :
5664
- ecmd -> supported |= SUPPORTED_10baseT_Half |
5665
- SUPPORTED_10baseT_Full |
5666
- SUPPORTED_100baseT_Half |
5667
- SUPPORTED_100baseT_Full |
5668
- SUPPORTED_1000baseT_Half |
5669
- SUPPORTED_1000baseT_Full |
5670
- SUPPORTED_10000baseT_Full |
5671
- SUPPORTED_FIBRE ;
5672
- ecmd -> advertising |= ADVERTISED_10baseT_Half |
5673
- ADVERTISED_10baseT_Full |
5674
- ADVERTISED_100baseT_Half |
5675
- ADVERTISED_100baseT_Full |
5676
- ADVERTISED_1000baseT_Half |
5677
- ADVERTISED_1000baseT_Full |
5678
- ADVERTISED_10000baseT_Full |
5679
- ADVERTISED_FIBRE ;
5730
+ qeth_set_ecmd_adv_sup (ecmd , SPEED_10000 , PORT_FIBRE );
5680
5731
ecmd -> speed = SPEED_10000 ;
5681
5732
ecmd -> port = PORT_FIBRE ;
5682
5733
break ;
5683
5734
5684
5735
default :
5685
- ecmd -> supported |= SUPPORTED_10baseT_Half |
5686
- SUPPORTED_10baseT_Full |
5687
- SUPPORTED_TP ;
5688
- ecmd -> advertising |= ADVERTISED_10baseT_Half |
5689
- ADVERTISED_10baseT_Full |
5690
- ADVERTISED_TP ;
5736
+ qeth_set_ecmd_adv_sup (ecmd , SPEED_10 , PORT_TP );
5691
5737
ecmd -> speed = SPEED_10 ;
5692
5738
ecmd -> port = PORT_TP ;
5693
5739
}
5694
5740
5741
+ /* Check if we can obtain more accurate information. */
5742
+ /* If QUERY_CARD_INFO command is not supported or fails, */
5743
+ /* just return the heuristics that was filled above. */
5744
+ if (qeth_query_card_info (card , & carrier_info ) != 0 )
5745
+ return 0 ;
5746
+
5747
+ netdev_dbg (netdev ,
5748
+ "card info: card_type=0x%02x, port_mode=0x%04x, port_speed=0x%08x\n" ,
5749
+ carrier_info .card_type ,
5750
+ carrier_info .port_mode ,
5751
+ carrier_info .port_speed );
5752
+
5753
+ /* Update attributes for which we've obtained more authoritative */
5754
+ /* information, leave the rest the way they where filled above. */
5755
+ switch (carrier_info .card_type ) {
5756
+ case CARD_INFO_TYPE_1G_COPPER_A :
5757
+ case CARD_INFO_TYPE_1G_COPPER_B :
5758
+ qeth_set_ecmd_adv_sup (ecmd , SPEED_1000 , PORT_TP );
5759
+ ecmd -> port = PORT_TP ;
5760
+ break ;
5761
+ case CARD_INFO_TYPE_1G_FIBRE_A :
5762
+ case CARD_INFO_TYPE_1G_FIBRE_B :
5763
+ qeth_set_ecmd_adv_sup (ecmd , SPEED_1000 , PORT_FIBRE );
5764
+ ecmd -> port = PORT_FIBRE ;
5765
+ break ;
5766
+ case CARD_INFO_TYPE_10G_FIBRE_A :
5767
+ case CARD_INFO_TYPE_10G_FIBRE_B :
5768
+ qeth_set_ecmd_adv_sup (ecmd , SPEED_10000 , PORT_FIBRE );
5769
+ ecmd -> port = PORT_FIBRE ;
5770
+ break ;
5771
+ }
5772
+
5773
+ switch (carrier_info .port_mode ) {
5774
+ case CARD_INFO_PORTM_FULLDUPLEX :
5775
+ ecmd -> duplex = DUPLEX_FULL ;
5776
+ break ;
5777
+ case CARD_INFO_PORTM_HALFDUPLEX :
5778
+ ecmd -> duplex = DUPLEX_HALF ;
5779
+ break ;
5780
+ }
5781
+
5782
+ switch (carrier_info .port_speed ) {
5783
+ case CARD_INFO_PORTS_10M :
5784
+ ecmd -> speed = SPEED_10 ;
5785
+ break ;
5786
+ case CARD_INFO_PORTS_100M :
5787
+ ecmd -> speed = SPEED_100 ;
5788
+ break ;
5789
+ case CARD_INFO_PORTS_1G :
5790
+ ecmd -> speed = SPEED_1000 ;
5791
+ break ;
5792
+ case CARD_INFO_PORTS_10G :
5793
+ ecmd -> speed = SPEED_10000 ;
5794
+ break ;
5795
+ }
5796
+
5695
5797
return 0 ;
5696
5798
}
5697
5799
EXPORT_SYMBOL_GPL (qeth_core_ethtool_get_settings );
0 commit comments