~ubuntu-branches/ubuntu/precise/linux-ti-omap4/precise

« back to all changes in this revision

Viewing changes to drivers/net/bnx2x/bnx2x_dcb.c

  • Committer: Bazaar Package Importer
  • Author(s): Paolo Pisati
  • Date: 2011-06-29 15:23:51 UTC
  • mfrom: (26.1.1 natty-proposed)
  • Revision ID: james.westby@ubuntu.com-20110629152351-xs96tm303d95rpbk
Tags: 3.0.0-1200.2
* Rebased against 3.0.0-6.7
* BSP from TI based on 3.0.0

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/* bnx2x_dcb.c: Broadcom Everest network driver.
2
2
 *
3
 
 * Copyright 2009-2010 Broadcom Corporation
 
3
 * Copyright 2009-2011 Broadcom Corporation
4
4
 *
5
5
 * Unless you and Broadcom execute a separate written software license
6
6
 * agreement governing use of this software, this software is licensed to you
19
19
#include <linux/netdevice.h>
20
20
#include <linux/types.h>
21
21
#include <linux/errno.h>
 
22
#ifdef BCM_DCBNL
 
23
#include <linux/dcbnl.h>
 
24
#endif
22
25
 
23
26
#include "bnx2x.h"
24
27
#include "bnx2x_cmn.h"
482
485
        }
483
486
}
484
487
 
 
488
#ifdef BCM_DCBNL
 
489
static int bnx2x_dcbx_read_shmem_remote_mib(struct bnx2x *bp)
 
490
{
 
491
        struct lldp_remote_mib remote_mib = {0};
 
492
        u32 dcbx_remote_mib_offset = SHMEM2_RD(bp, dcbx_remote_mib_offset);
 
493
        int rc;
 
494
 
 
495
        DP(NETIF_MSG_LINK, "dcbx_remote_mib_offset 0x%x\n",
 
496
           dcbx_remote_mib_offset);
 
497
 
 
498
        if (SHMEM_DCBX_REMOTE_MIB_NONE == dcbx_remote_mib_offset) {
 
499
                BNX2X_ERR("FW doesn't support dcbx_remote_mib_offset\n");
 
500
                return -EINVAL;
 
501
        }
 
502
 
 
503
        rc = bnx2x_dcbx_read_mib(bp, (u32 *)&remote_mib, dcbx_remote_mib_offset,
 
504
                                 DCBX_READ_REMOTE_MIB);
 
505
 
 
506
        if (rc) {
 
507
                BNX2X_ERR("Faild to read remote mib from FW\n");
 
508
                return rc;
 
509
        }
 
510
 
 
511
        /* save features and flags */
 
512
        bp->dcbx_remote_feat = remote_mib.features;
 
513
        bp->dcbx_remote_flags = remote_mib.flags;
 
514
        return 0;
 
515
}
 
516
#endif
 
517
 
485
518
static int bnx2x_dcbx_read_shmem_neg_results(struct bnx2x *bp)
486
519
{
487
520
        struct lldp_local_mib local_mib = {0};
508
541
        return 0;
509
542
}
510
543
 
 
544
 
 
545
#ifdef BCM_DCBNL
 
546
static inline
 
547
u8 bnx2x_dcbx_dcbnl_app_up(struct dcbx_app_priority_entry *ent)
 
548
{
 
549
        u8 pri;
 
550
 
 
551
        /* Choose the highest priority */
 
552
        for (pri = MAX_PFC_PRIORITIES - 1; pri > 0; pri--)
 
553
                if (ent->pri_bitmap & (1 << pri))
 
554
                        break;
 
555
        return pri;
 
556
}
 
557
 
 
558
static inline
 
559
u8 bnx2x_dcbx_dcbnl_app_idtype(struct dcbx_app_priority_entry *ent)
 
560
{
 
561
        return ((ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) ==
 
562
                DCBX_APP_SF_PORT) ? DCB_APP_IDTYPE_PORTNUM :
 
563
                DCB_APP_IDTYPE_ETHTYPE;
 
564
}
 
565
 
 
566
static inline
 
567
void bnx2x_dcbx_invalidate_local_apps(struct bnx2x *bp)
 
568
{
 
569
        int i;
 
570
        for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
 
571
                bp->dcbx_local_feat.app.app_pri_tbl[i].appBitfield &=
 
572
                                                        ~DCBX_APP_ENTRY_VALID;
 
573
}
 
574
 
 
575
int bnx2x_dcbnl_update_applist(struct bnx2x *bp, bool delall)
 
576
{
 
577
        int i, err = 0;
 
578
 
 
579
        for (i = 0; i < DCBX_MAX_APP_PROTOCOL && err == 0; i++) {
 
580
                struct dcbx_app_priority_entry *ent =
 
581
                        &bp->dcbx_local_feat.app.app_pri_tbl[i];
 
582
 
 
583
                if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
 
584
                        u8 up = bnx2x_dcbx_dcbnl_app_up(ent);
 
585
 
 
586
                        /* avoid invalid user-priority */
 
587
                        if (up) {
 
588
                                struct dcb_app app;
 
589
                                app.selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
 
590
                                app.protocol = ent->app_id;
 
591
                                app.priority = delall ? 0 : up;
 
592
                                err = dcb_setapp(bp->dev, &app);
 
593
                        }
 
594
                }
 
595
        }
 
596
        return err;
 
597
}
 
598
#endif
 
599
 
511
600
void bnx2x_dcbx_set_params(struct bnx2x *bp, u32 state)
512
601
{
513
602
        switch (state) {
514
603
        case BNX2X_DCBX_STATE_NEG_RECEIVED:
 
604
#ifdef BCM_CNIC
 
605
                if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
 
606
                        struct cnic_ops *c_ops;
 
607
                        struct cnic_eth_dev *cp = &bp->cnic_eth_dev;
 
608
                        bp->flags |= NO_ISCSI_OOO_FLAG | NO_ISCSI_FLAG;
 
609
                        cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI_OOO;
 
610
                        cp->drv_state |= CNIC_DRV_STATE_NO_ISCSI;
 
611
 
 
612
                        rcu_read_lock();
 
613
                        c_ops = rcu_dereference(bp->cnic_ops);
 
614
                        if (c_ops) {
 
615
                                bnx2x_cnic_notify(bp, CNIC_CTL_STOP_ISCSI_CMD);
 
616
                                rcu_read_unlock();
 
617
                                return;
 
618
                        }
 
619
                        rcu_read_unlock();
 
620
                }
 
621
 
 
622
                /* fall through if no CNIC initialized  */
 
623
        case BNX2X_DCBX_STATE_ISCSI_STOPPED:
 
624
#endif
 
625
 
515
626
                {
516
627
                        DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_NEG_RECEIVED\n");
 
628
#ifdef BCM_DCBNL
 
629
                        /**
 
630
                         * Delete app tlvs from dcbnl before reading new
 
631
                         * negotiation results
 
632
                         */
 
633
                        bnx2x_dcbnl_update_applist(bp, true);
517
634
 
 
635
                        /* Read rmeote mib if dcbx is in the FW */
 
636
                        if (bnx2x_dcbx_read_shmem_remote_mib(bp))
 
637
                                return;
 
638
#endif
518
639
                        /* Read neg results if dcbx is in the FW */
519
640
                        if (bnx2x_dcbx_read_shmem_neg_results(bp))
520
641
                                return;
526
647
                                                 bp->dcbx_error);
527
648
 
528
649
                        if (bp->state != BNX2X_STATE_OPENING_WAIT4_LOAD) {
 
650
#ifdef BCM_DCBNL
 
651
                                /**
 
652
                                 * Add new app tlvs to dcbnl
 
653
                                 */
 
654
                                bnx2x_dcbnl_update_applist(bp, false);
 
655
#endif
529
656
                                bnx2x_dcbx_stop_hw_tx(bp);
530
657
                                return;
531
658
                        }
532
659
                        /* fall through */
 
660
#ifdef BCM_DCBNL
 
661
                        /**
 
662
                         * Invalidate the local app tlvs if they are not added
 
663
                         * to the dcbnl app list to avoid deleting them from
 
664
                         * the list later on
 
665
                         */
 
666
                        bnx2x_dcbx_invalidate_local_apps(bp);
 
667
#endif
533
668
                }
534
669
        case BNX2X_DCBX_STATE_TX_PAUSED:
535
670
                DP(NETIF_MSG_LINK, "BNX2X_DCBX_STATE_TX_PAUSED\n");
978
1113
        }
979
1114
}
980
1115
 
981
 
 
982
 
/*******************************************************************************
983
 
 * Description: single priority group
984
 
 *
985
 
 * Return:
986
 
 ******************************************************************************/
987
1116
static void bnx2x_dcbx_ets_disabled_entry_data(struct bnx2x *bp,
988
1117
                                               struct cos_help_data *cos_data,
989
1118
                                               u32 pri_join_mask)
996
1125
        cos_data->num_of_cos = 1;
997
1126
}
998
1127
 
999
 
/*******************************************************************************
1000
 
 * Description: updating the cos bw
1001
 
 *
1002
 
 * Return:
1003
 
 ******************************************************************************/
1004
1128
static inline void bnx2x_dcbx_add_to_cos_bw(struct bnx2x *bp,
1005
1129
                                            struct cos_entry_help_data *data,
1006
1130
                                            u8 pg_bw)
1011
1135
                data->cos_bw += pg_bw;
1012
1136
}
1013
1137
 
1014
 
/*******************************************************************************
1015
 
 * Description: single priority group
1016
 
 *
1017
 
 * Return:
1018
 
 ******************************************************************************/
1019
1138
static void bnx2x_dcbx_separate_pauseable_from_non(struct bnx2x *bp,
1020
1139
                        struct cos_help_data *cos_data,
1021
1140
                        u32 *pg_pri_orginal_spread,
1268
1387
        }
1269
1388
}
1270
1389
 
1271
 
/*******************************************************************************
1272
 
 * Description: Still
1273
 
 *
1274
 
 * Return:
1275
 
 ******************************************************************************/
1276
1390
static void bnx2x_dcbx_three_pg_to_cos_params(
1277
1391
                              struct bnx2x              *bp,
1278
1392
                              struct pg_help_data       *pg_help_data,
1460
1574
        }
1461
1575
}
1462
1576
 
1463
 
/*******************************************************************************
1464
 
 * Description: Fill pfc_config struct that will be sent in DCBX start ramrod
1465
 
 *
1466
 
 * Return:
1467
 
 ******************************************************************************/
1468
1577
static void bnx2x_pfc_fw_struct_e2(struct bnx2x *bp)
1469
1578
{
1470
1579
        struct flow_control_configuration   *pfc_fw_cfg = NULL;
1505
1614
        bnx2x_dcbx_print_cos_params(bp, pfc_fw_cfg);
1506
1615
}
1507
1616
/* DCB netlink */
1508
 
#ifdef BCM_DCB
1509
 
#include <linux/dcbnl.h>
 
1617
#ifdef BCM_DCBNL
1510
1618
 
1511
1619
#define BNX2X_DCBX_CAPS         (DCB_CAP_DCBX_LLD_MANAGED | \
1512
1620
                                DCB_CAP_DCBX_VER_CEE | DCB_CAP_DCBX_STATIC)
1816
1924
        bp->dcbx_config_params.admin_pfc_enable = (state ? 1 : 0);
1817
1925
}
1818
1926
 
1819
 
static bool bnx2x_app_is_equal(struct dcbx_app_priority_entry *app_ent,
1820
 
                               u8 idtype, u16 idval)
1821
 
{
1822
 
        if (!(app_ent->appBitfield & DCBX_APP_ENTRY_VALID))
1823
 
                return false;
1824
 
 
1825
 
        switch (idtype) {
1826
 
        case DCB_APP_IDTYPE_ETHTYPE:
1827
 
                if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) !=
1828
 
                        DCBX_APP_SF_ETH_TYPE)
1829
 
                        return false;
1830
 
                break;
1831
 
        case DCB_APP_IDTYPE_PORTNUM:
1832
 
                if ((app_ent->appBitfield & DCBX_APP_ENTRY_SF_MASK) !=
1833
 
                        DCBX_APP_SF_PORT)
1834
 
                        return false;
1835
 
                break;
1836
 
        default:
1837
 
                return false;
1838
 
        }
1839
 
        if (app_ent->app_id != idval)
1840
 
                return false;
1841
 
 
1842
 
        return true;
1843
 
}
1844
 
 
1845
1927
static void bnx2x_admin_app_set_ent(
1846
1928
        struct bnx2x_admin_priority_app_table *app_ent,
1847
1929
        u8 idtype, u16 idval, u8 up)
1943
2025
        return bnx2x_set_admin_app_up(bp, idtype, idval, up);
1944
2026
}
1945
2027
 
1946
 
static u8 bnx2x_dcbnl_get_app_up(struct net_device *netdev, u8 idtype,
1947
 
                                 u16 idval)
1948
 
{
1949
 
        int i;
1950
 
        u8 up = 0;
1951
 
 
1952
 
        struct bnx2x *bp = netdev_priv(netdev);
1953
 
        DP(NETIF_MSG_LINK, "app_type %d, app_id 0x%x\n", idtype, idval);
1954
 
 
1955
 
        /* iterate over the app entries looking for idtype and idval */
1956
 
        for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
1957
 
                if (bnx2x_app_is_equal(&bp->dcbx_local_feat.app.app_pri_tbl[i],
1958
 
                                       idtype, idval))
1959
 
                        break;
1960
 
 
1961
 
        if (i < DCBX_MAX_APP_PROTOCOL)
1962
 
                /* if found return up */
1963
 
                up = bp->dcbx_local_feat.app.app_pri_tbl[i].pri_bitmap;
1964
 
        else
1965
 
                DP(NETIF_MSG_LINK, "app not found\n");
1966
 
 
1967
 
        return up;
1968
 
}
1969
 
 
1970
2028
static u8 bnx2x_dcbnl_get_dcbx(struct net_device *netdev)
1971
2029
{
1972
2030
        struct bnx2x *bp = netdev_priv(netdev);
2007
2065
        return 0;
2008
2066
}
2009
2067
 
2010
 
 
2011
2068
static u8 bnx2x_dcbnl_get_featcfg(struct net_device *netdev, int featid,
2012
2069
                                  u8 *flags)
2013
2070
{
2087
2144
        return rval;
2088
2145
}
2089
2146
 
 
2147
static int bnx2x_peer_appinfo(struct net_device *netdev,
 
2148
                              struct dcb_peer_app_info *info, u16* app_count)
 
2149
{
 
2150
        int i;
 
2151
        struct bnx2x *bp = netdev_priv(netdev);
 
2152
 
 
2153
        DP(NETIF_MSG_LINK, "APP-INFO\n");
 
2154
 
 
2155
        info->willing = (bp->dcbx_remote_flags & DCBX_APP_REM_WILLING) ?: 0;
 
2156
        info->error = (bp->dcbx_remote_flags & DCBX_APP_RX_ERROR) ?: 0;
 
2157
        *app_count = 0;
 
2158
 
 
2159
        for (i = 0; i < DCBX_MAX_APP_PROTOCOL; i++)
 
2160
                if (bp->dcbx_remote_feat.app.app_pri_tbl[i].appBitfield &
 
2161
                    DCBX_APP_ENTRY_VALID)
 
2162
                        (*app_count)++;
 
2163
        return 0;
 
2164
}
 
2165
 
 
2166
static int bnx2x_peer_apptable(struct net_device *netdev,
 
2167
                               struct dcb_app *table)
 
2168
{
 
2169
        int i, j;
 
2170
        struct bnx2x *bp = netdev_priv(netdev);
 
2171
 
 
2172
        DP(NETIF_MSG_LINK, "APP-TABLE\n");
 
2173
 
 
2174
        for (i = 0, j = 0; i < DCBX_MAX_APP_PROTOCOL; i++) {
 
2175
                struct dcbx_app_priority_entry *ent =
 
2176
                        &bp->dcbx_remote_feat.app.app_pri_tbl[i];
 
2177
 
 
2178
                if (ent->appBitfield & DCBX_APP_ENTRY_VALID) {
 
2179
                        table[j].selector = bnx2x_dcbx_dcbnl_app_idtype(ent);
 
2180
                        table[j].priority = bnx2x_dcbx_dcbnl_app_up(ent);
 
2181
                        table[j++].protocol = ent->app_id;
 
2182
                }
 
2183
        }
 
2184
        return 0;
 
2185
}
 
2186
 
 
2187
static int bnx2x_cee_peer_getpg(struct net_device *netdev, struct cee_pg *pg)
 
2188
{
 
2189
        int i;
 
2190
        struct bnx2x *bp = netdev_priv(netdev);
 
2191
 
 
2192
        pg->willing = (bp->dcbx_remote_flags & DCBX_ETS_REM_WILLING) ?: 0;
 
2193
 
 
2194
        for (i = 0; i < CEE_DCBX_MAX_PGS; i++) {
 
2195
                pg->pg_bw[i] =
 
2196
                        DCBX_PG_BW_GET(bp->dcbx_remote_feat.ets.pg_bw_tbl, i);
 
2197
                pg->prio_pg[i] =
 
2198
                        DCBX_PRI_PG_GET(bp->dcbx_remote_feat.ets.pri_pg_tbl, i);
 
2199
        }
 
2200
        return 0;
 
2201
}
 
2202
 
 
2203
static int bnx2x_cee_peer_getpfc(struct net_device *netdev,
 
2204
                                 struct cee_pfc *pfc)
 
2205
{
 
2206
        struct bnx2x *bp = netdev_priv(netdev);
 
2207
        pfc->tcs_supported = bp->dcbx_remote_feat.pfc.pfc_caps;
 
2208
        pfc->pfc_en = bp->dcbx_remote_feat.pfc.pri_en_bitmap;
 
2209
        return 0;
 
2210
}
 
2211
 
2090
2212
const struct dcbnl_rtnl_ops bnx2x_dcbnl_ops = {
2091
 
        .getstate       = bnx2x_dcbnl_get_state,
2092
 
        .setstate       = bnx2x_dcbnl_set_state,
2093
 
        .getpermhwaddr  = bnx2x_dcbnl_get_perm_hw_addr,
2094
 
        .setpgtccfgtx   = bnx2x_dcbnl_set_pg_tccfg_tx,
2095
 
        .setpgbwgcfgtx  = bnx2x_dcbnl_set_pg_bwgcfg_tx,
2096
 
        .setpgtccfgrx   = bnx2x_dcbnl_set_pg_tccfg_rx,
2097
 
        .setpgbwgcfgrx  = bnx2x_dcbnl_set_pg_bwgcfg_rx,
2098
 
        .getpgtccfgtx   = bnx2x_dcbnl_get_pg_tccfg_tx,
2099
 
        .getpgbwgcfgtx  = bnx2x_dcbnl_get_pg_bwgcfg_tx,
2100
 
        .getpgtccfgrx   = bnx2x_dcbnl_get_pg_tccfg_rx,
2101
 
        .getpgbwgcfgrx  = bnx2x_dcbnl_get_pg_bwgcfg_rx,
2102
 
        .setpfccfg      = bnx2x_dcbnl_set_pfc_cfg,
2103
 
        .getpfccfg      = bnx2x_dcbnl_get_pfc_cfg,
2104
 
        .setall         = bnx2x_dcbnl_set_all,
2105
 
        .getcap         = bnx2x_dcbnl_get_cap,
2106
 
        .getnumtcs      = bnx2x_dcbnl_get_numtcs,
2107
 
        .setnumtcs      = bnx2x_dcbnl_set_numtcs,
2108
 
        .getpfcstate    = bnx2x_dcbnl_get_pfc_state,
2109
 
        .setpfcstate    = bnx2x_dcbnl_set_pfc_state,
2110
 
        .getapp         = bnx2x_dcbnl_get_app_up,
2111
 
        .setapp         = bnx2x_dcbnl_set_app_up,
2112
 
        .getdcbx        = bnx2x_dcbnl_get_dcbx,
2113
 
        .setdcbx        = bnx2x_dcbnl_set_dcbx,
2114
 
        .getfeatcfg     = bnx2x_dcbnl_get_featcfg,
2115
 
        .setfeatcfg     = bnx2x_dcbnl_set_featcfg,
 
2213
        .getstate               = bnx2x_dcbnl_get_state,
 
2214
        .setstate               = bnx2x_dcbnl_set_state,
 
2215
        .getpermhwaddr          = bnx2x_dcbnl_get_perm_hw_addr,
 
2216
        .setpgtccfgtx           = bnx2x_dcbnl_set_pg_tccfg_tx,
 
2217
        .setpgbwgcfgtx          = bnx2x_dcbnl_set_pg_bwgcfg_tx,
 
2218
        .setpgtccfgrx           = bnx2x_dcbnl_set_pg_tccfg_rx,
 
2219
        .setpgbwgcfgrx          = bnx2x_dcbnl_set_pg_bwgcfg_rx,
 
2220
        .getpgtccfgtx           = bnx2x_dcbnl_get_pg_tccfg_tx,
 
2221
        .getpgbwgcfgtx          = bnx2x_dcbnl_get_pg_bwgcfg_tx,
 
2222
        .getpgtccfgrx           = bnx2x_dcbnl_get_pg_tccfg_rx,
 
2223
        .getpgbwgcfgrx          = bnx2x_dcbnl_get_pg_bwgcfg_rx,
 
2224
        .setpfccfg              = bnx2x_dcbnl_set_pfc_cfg,
 
2225
        .getpfccfg              = bnx2x_dcbnl_get_pfc_cfg,
 
2226
        .setall                 = bnx2x_dcbnl_set_all,
 
2227
        .getcap                 = bnx2x_dcbnl_get_cap,
 
2228
        .getnumtcs              = bnx2x_dcbnl_get_numtcs,
 
2229
        .setnumtcs              = bnx2x_dcbnl_set_numtcs,
 
2230
        .getpfcstate            = bnx2x_dcbnl_get_pfc_state,
 
2231
        .setpfcstate            = bnx2x_dcbnl_set_pfc_state,
 
2232
        .setapp                 = bnx2x_dcbnl_set_app_up,
 
2233
        .getdcbx                = bnx2x_dcbnl_get_dcbx,
 
2234
        .setdcbx                = bnx2x_dcbnl_set_dcbx,
 
2235
        .getfeatcfg             = bnx2x_dcbnl_get_featcfg,
 
2236
        .setfeatcfg             = bnx2x_dcbnl_set_featcfg,
 
2237
        .peer_getappinfo        = bnx2x_peer_appinfo,
 
2238
        .peer_getapptable       = bnx2x_peer_apptable,
 
2239
        .cee_peer_getpg         = bnx2x_cee_peer_getpg,
 
2240
        .cee_peer_getpfc        = bnx2x_cee_peer_getpfc,
2116
2241
};
2117
2242
 
2118
 
#endif /* BCM_DCB */
 
2243
#endif /* BCM_DCBNL */