]> git.openfabrics.org - ~adrianc/mstflint.git/commitdiff
Update code to mft-2.7.1 release
authorOren Kladnitsky <orenk@dev.mellanox.co.il>
Wed, 26 Oct 2011 12:12:14 +0000 (14:12 +0200)
committerOren Kladnitsky <orenk@dev.mellanox.co.il>
Wed, 26 Oct 2011 12:12:14 +0000 (14:12 +0200)
Atmel flash support
Clearer error message on device/image mismatch
Version string fix

flint.cpp
mflash.c
tools_version.h

index 3fd18d72e5a034042ce590d8347a2b113f651736..d57b35020bc4f678c84e741ba680f08918fcab9d 100644 (file)
--- a/flint.cpp
+++ b/flint.cpp
@@ -32,7 +32,7 @@
  * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
  * SOFTWARE.
  *
- *  Version: $Id: flint.cpp 7187 2011-07-05 11:53:16Z orenk $
+ *  Version: $Id: flint.cpp 7425 2011-10-03 15:26:25Z mohammad $
  *
  */
 
 #include <fcntl.h>
 #include <assert.h>
 #include <time.h>
-#include <termios.h>
 
 
 #include "tools_version.h"
 
-#ifndef NO_ZLIB
-    #include <zlib.h>
-#endif
 
 #include <signal.h>
 
@@ -83,7 +79,7 @@
         #define vsnprintf(buf, len, format, args) (vsprintf(buf, format, args))
 
     #else // Linux GCC
-
+        #include <termios.h>
         #include <byteswap.h>
         #include <endian.h>
         #include <alloca.h>
     #define sleep(x)  Sleep((x)*1000)
 
     #define vsnprintf      _vsnprintf
-    #define strtoull       _strtoui64
     #define isatty         _isatty
 
     #define COMP_CDECL     __cdecl
     #define __BYTE_ORDER __LITTLE_ENDIAN
 
 
+
     #if __BYTE_ORDER == __LITTLE_ENDIAN
         #define bswap_32(x) ntohl(x)
     #else
         #error windows is assumed to run a on little endian architecture
     #endif
 
+    // MINGW
+    #if defined(__MINGW32__) || (__MINGW64__)
+        #define strtoull       strtoull
+        #define _UNISTD_H // Zlib includes unistd.h which causes some compilation errors.
+
+    #else
+        #define strtoull       _strtoui64
+    #endif
 #endif // __WIN__
 
+#ifndef NO_ZLIB
+    #include <zlib.h>
+#endif
+
+
 #include <memory>
 #include <vector>
 
@@ -206,6 +215,7 @@ static inline void cpu_to_be_guid(guid_t* to, guid_t* from) {
 }
 #define FLASH_PARAMS_OPTS "<type,log2size,num_of_flashes>"
 #define MAX_NUM_SUPP_HW_IDS 200
+#define MAX_NUM_SUPP_HW_LIST_STR (MAX_NUM_SUPP_HW_IDS * 40)
 #define MAC_SPACES  "            "
 #define GUID_SPACES "        "
 #define GUID_FORMAT "%8.8x%8.8x"
@@ -1554,6 +1564,8 @@ public:
     bool CheckMatchingDevId(u_int32_t hwDevId, u_int32_t imageDevId);
     bool CheckMatchingExpRomDevId(Operations::ImageInfo* info);
     bool HwDevIdToSw(u_int32_t hw_dev_id, u_int32_t& sw_dev_id);
+    bool HWIdRevToName(u_int32_t hw_id, u_int8_t rev_id, char *hw_name);
+
     // Image operations:
     bool Verify          (FBase& f, ImageInfo* info, bool both_images = false);
     bool VerifyFs2      (FBase& f, ImageInfo* info, bool both_images = false, bool only_get_start = false,
@@ -1864,6 +1876,12 @@ public:
         const u_int32_t  swDevIds[MAX_SW_DEVICES_PER_HW];
     };
 
+    struct HwDev2Str {
+        const char*      name;
+        u_int32_t        hwDevId;
+        u_int8_t         revId;
+    };
+
     bool FwVerLessThan(u_int16_t r1[3], u_int16_t r2[3]) {
         int i;
         for (i = 0; i < 3 ; i++)
@@ -1952,6 +1970,7 @@ private:
     bool      _is_full_verify;
     bool      _ignore_tty;
     static const HwDevData hwDevData[];
+    static const HwDev2Str hwDev2Str[];
 
     std::vector<u_int8_t>  _fw_conf_sect;
     std::vector<u_int8_t>  _hash_file_sect;
@@ -1975,25 +1994,50 @@ const u_int32_t Operations::_cntx_image_start_pos[Operations::CNTX_START_POS_SIZ
     0x100000,
     0x200000
 };
-#define CX3_HW_ID 501
+#define CX3_HW_ID        501
+#define CX_HW_ID         400
+#define IS_HW_ID         435
+#define BRIDGEX_HW_ID    6100
+#define IS4_HW_ID        435
+#define TAVOR_HW_ID      23108
+#define ARBEL_HW_ID      25208
+#define SINAI_HW_ID      25204
+
 const Operations::HwDevData Operations::hwDevData[] = {
-    { "InfiniHost",        23108, 2, {23108, 0}},
-    { "InfiniHost III Ex", 25208, 2, {25208, 25218, 0}},
-    { "InfiniHost III Lx", 25204, 1, {25204, 0}},
-    { "ConnectX",            400, 2, {25408, 25418, 26418, 26438,
-                                      26428, 25448, 26448, 26468,
-                                      25458, 26458, 26478, 26488,
-                                      4097, 4098, 4100,
-                                      4101, 4102, 4103, 4104,
-                                      4105, 4106, 4107, 4108,
-                                      4109, 4110, 4111, 4112, 0}},
-    { "ConnectX3",        CX3_HW_ID, 2, {4099}},
-    { "InfiniScale IV",   435,  0, {48436, 48437, 48438, 0}},
-    { "BridgeX",          6100, 0, {64102, 64112, 64122, 0}},
+    { "InfiniHost",        TAVOR_HW_ID, 2, {23108, 0}},
+    { "InfiniHost III Ex", ARBEL_HW_ID, 2, {25208, 25218, 0}},
+    { "InfiniHost III Lx", SINAI_HW_ID, 1, {25204, 0}},
+    { "ConnectX",          CX_HW_ID, 2, {25408, 25418, 26418, 26438,
+                                         26428, 25448, 26448, 26468,
+                                         25458, 26458, 26478, 26488,
+                                         4097, 4098, 0}},
+    { "ConnectX3",        CX3_HW_ID, 2, {4099, 4100, 4101, 4102,
+                                         4103, 4104, 4105, 4106,
+                                         4107, 4108, 4109, 4110,
+                                         4111, 4112, 0}},
+    { "InfiniScale IV",   IS4_HW_ID,  0, {48436, 48437, 48438, 0}},
+    { "BridgeX",          BRIDGEX_HW_ID, 0, {64102, 64112, 64122, 0}},
     { "SwitchX",          SWITCHX_HW_ID,  0, {51000, 0}},
     { NULL ,              0, 0, {0}},// zero devid terminator
 };
 
+const Operations::HwDev2Str Operations::hwDev2Str[] = {
+        {"ConnectX",          CX_HW_ID,      0xA0},
+        {"ConnectX-2",        CX_HW_ID,      0xB0},
+        {"ConnectX-3 A0",     CX3_HW_ID,     0x00},
+        {"ConnectX-3 A1",     CX3_HW_ID,     0x01},
+        {"SwitchX A0",        SWITCHX_HW_ID, 0x00},
+        {"SwitchX A1",        SWITCHX_HW_ID, 0x01},
+        {"BridgeX",           BRIDGEX_HW_ID, 0xA0},
+        {"InfiniScale IV A0", IS4_HW_ID,     0xA0},
+        {"InfiniScale IV A1", IS4_HW_ID,     0xA1},
+        {"InfiniHost A0",     TAVOR_HW_ID,   0xA0},
+        {"InfiniHost A1",     TAVOR_HW_ID,   0xA1},
+        {"InfiniHost III Lx", SINAI_HW_ID,   0xA0},
+        {"InfiniHost III Ex", ARBEL_HW_ID,   0xA0},
+        { NULL ,              0,             0x00}, // zero devid terminator
+};
+
 //
 // Asks user a yes/no question.
 // Returns true if user chose Y, false if user chose N.
@@ -3176,6 +3220,28 @@ bool Operations::HwDevIdToSw(u_int32_t hw_dev_id, u_int32_t& sw_dev_id)
     }
     return errmsg("Unknown Hw ID: %#x\n", hw_dev_id);
 }
+#define ARR_SIZE(arr) sizeof(arr)/sizeof(arr[0])
+#define MAX_HW_NAME_LEN 100
+bool Operations::HWIdRevToName(u_int32_t hw_id, u_int8_t rev_id, char *hw_name)
+{
+    int i;
+
+    for (i = 0;  hwDev2Str[i].hwDevId != 0; i++) {
+        const HwDev2Str *hwDev2StrMem = &(hwDev2Str[i]);
+
+        if (hwDev2StrMem->hwDevId == hw_id && hwDev2StrMem->revId == rev_id) {
+            int len = strlen(hwDev2StrMem->name);
+            if (len >= MAX_HW_NAME_LEN) {
+                return errmsg("Internal error: Length of device name: %d exceeds the maximum allowed size: %d", len, MAX_HW_NAME_LEN - 1);
+            }
+            strcpy(hw_name, hwDev2StrMem->name);
+            return true;
+        }
+    }
+    // When the device or rev is unknown we use the hw ID and rev to display it.
+    sprintf(hw_name, "MT%d-%02X", hw_id, rev_id);
+    return true;
+}
 
 // This function gets the HW ID of the target device and the dev ID from
 // the image. It then matches the 2 IDs and returns an error in case of
@@ -3185,22 +3251,51 @@ bool Operations::HwDevIdToSw(u_int32_t hw_dev_id, u_int32_t& sw_dev_id)
 bool Operations::CheckMatchingHwDevId(u_int32_t hwDevId, u_int32_t rev_id, Operations::ImageInfo& info) {
 
     int i;
-    u_int32_t sw_dev_id;
+    char supp_hw_id_list[MAX_NUM_SUPP_HW_LIST_STR] = {'\0'};
+    char curr_hw_id_name[MAX_HW_NAME_LEN];
 
-    if (!HwDevIdToSw(hwDevId, sw_dev_id)) {
-        return false;
-    }
-    u_int32_t hw_dev_rev = (hwDevId & 0xffff) | ((rev_id & 0xff) << 16);
     for (i = 0; i < info.supportedHwIdNum; i++) {
-        //printf("-D- hw_dev_rev: %#x,  supported_hw_id[%d]: %#x\n", hw_dev_rev, i, supported_hw_id[i]);
-        if (info.supportedHwId[i] == hw_dev_rev) {
+        u_int32_t currSupportedHwId = info.supportedHwId[i];
+        u_int32_t supp_hw_id  = currSupportedHwId & 0xffff;
+        u_int32_t supp_rev_id = (currSupportedHwId >> 16) & 0xff;
+        u_int32_t tmp_size_of_list;
+        char hw_name[MAX_HW_NAME_LEN];
+
+        if (currSupportedHwId == 0) {
+            break;
+        }
+        // Check if device is supported!
+        if ( supp_hw_id == hwDevId && supp_rev_id == rev_id) {
             return true;
         }
+        // Append checked to list of supported device in order to print it in the error if we this device is not supported
+
+        // Get the HW name of current supported HW ID
+        if (!HWIdRevToName(supp_hw_id, supp_rev_id, hw_name)) {
+            return false;
+        }
+        // Check if we don't exceed the array size we have
+        tmp_size_of_list = strlen(supp_hw_id_list) + strlen(hw_name) + 2;
+        if (tmp_size_of_list >= MAX_NUM_SUPP_HW_LIST_STR) {
+            return errmsg("Internal error: Size of supported devs list: %d exceeds the maximum allowed size: %d",
+                    tmp_size_of_list, MAX_NUM_SUPP_HW_LIST_STR - 1);
+        }
+
+        if (supp_hw_id_list[0] == '\0') {
+            sprintf(supp_hw_id_list, "%s", hw_name);
+        } else {
+            sprintf(supp_hw_id_list, "%s, %s", supp_hw_id_list, hw_name);
+        }
+    }
+    // If we get here, this FW cannot be burnt in the current device.
+    // Get the Device name
+    if (!HWIdRevToName(hwDevId, rev_id, curr_hw_id_name)) {
+        return false;
     }
-    return errmsg("FW image file for device MT%d%X can not be programmed to device MT%d%X",
-                  info.devType, info.devRev, sw_dev_id, rev_id);
-}
 
+    return errmsg("FW image file cannot be programmed to device %s, it is intended for: %s only",
+            curr_hw_id_name, supp_hw_id_list);
+}
 bool Operations::CheckMatchingDevId(u_int32_t hwDevId, u_int32_t imageDevId) {
     int i, j;
     const HwDevData* devData = NULL;
@@ -3896,7 +3991,7 @@ bool Operations::DumpConf        (const char* conf_file, SectionType sect_type)
                         (const Bytef *)&(file_sect[0]), file_sect.size());
 
     if (rc != Z_OK) {
-        return errmsg("Failed uncompressing FW configuration section. uncompress returnes %d", rc);
+        return errmsg("Failed uncompressing FW configuration section. uncompress returns %d", rc);
     }
 
     dest.resize(destLen);
@@ -3944,7 +4039,6 @@ u_int32_t Operations::BSN_subfield(const char *s, int beg, int len)
     return strtoul(&buf[0], 0, 10);
 }
 
-#define ARR_SIZE(arr) sizeof(arr)/sizeof(arr[0])
 
 bool Operations::getFlashParams(char *flash_arg, flash_params_t *flash_params)
 {
@@ -5568,10 +5662,6 @@ MAN_BR
     "                         to ensure failsafe burning even when an invariant sector difference is detected.\n"
     "                         See the specific FW release notes for more details.\n"
     "\n"
-    "    -byte_mode         - Shift address when accessing flash internal registers. May\n"
-    "                         be required for burn/write commands when accessing certain\n"
-    "                         flash types.\n"
-    "\n"
     "    -no_flash_verify   - Do not verify each write on the flash.\n"
     "\n"
 #if 0
@@ -6673,6 +6763,8 @@ void PrintFSBurnErr(Flash& f, Operations& ops, const char* operation)
         }\
 }
 
+#define MAX_PASSWORD_LEN 256
+#ifndef __WIN__
 int mygetch(void)
 {
     struct termios oldt,
@@ -6686,7 +6778,6 @@ int mygetch(void)
     tcsetattr( STDIN_FILENO, TCSANOW, &oldt );
     return ch;
 }
-#define MAX_PASSWORD_LEN 256
 // TODO: Move this function to the tools common file.
 int GetPasswordFromUser(char *pre_str, char buffer[MAX_PASSWORD_LEN])
 {
@@ -6711,6 +6802,16 @@ int GetPasswordFromUser(char *pre_str, char buffer[MAX_PASSWORD_LEN])
     return true;
 }
 
+#else
+int GetPasswordFromUser(char *pre_str, char buffer[MAX_PASSWORD_LEN])
+{
+    printf("%s: ", pre_str);
+    scanf("%s", buffer);
+    return true;
+}
+
+#endif
+
 int main(int ac, char *av[])
 {
 
index d84be2761c055c6b90cf07beebcb54076afa6a1c..dbcf7c3044e9a0f9730d1ed00186898be30a65bf 100644 (file)
--- a/mflash.c
+++ b/mflash.c
@@ -63,6 +63,7 @@
 #define __cpu_to_be32(val) (val)
 #endif
 #endif
+#define OP_NOT_SUPPORTED EOPNOTSUPP
 
 #else // __WIN__
 
@@ -77,6 +78,8 @@
 #define inline __inline
 #define __cpu_to_be32(val) SWAPL(val) // Win is only run on LE CPUS
 
+#define OP_NOT_SUPPORTED EINVAL
+
 #endif // __WIN__
 #endif
 
@@ -172,12 +175,12 @@ struct mflash {
 #else
 #define MREAD4(offs, val)  do { if (mread4 (mfl->mf, offs, val) != 4) { \
                                   fprintf(stderr, "-E- Cr read (0x%08x) failed: %s(%d)\n", (u_int32_t)(offs), strerror(errno), (u_int32_t)errno); \
-                  exit(2); } /*printf("-D- mread4: offs = %#x, val = %#x\n", offs, val);*/  \
+                  exit(2); } /*printf("-D- %s:%d mread4: offs = %#x, val = %#x\n", __FUNCTION__, __LINE__, offs, val);*/  \
                                   } while (0)
 
 #define MWRITE4(offs, val) do { if (mwrite4(mfl->mf, offs, val) != 4) { \
                                   fprintf(stderr, "-E- Cr write (0x%08x, 0x%08x) failed: %s(%d)\n", (u_int32_t)(offs), (u_int32_t)(val), strerror(errno), (u_int32_t)errno); \
-                  mclose(mfl->mf); exit(2); } /*printf("-D- %s mwrite4: offs = %#x, val = %#x\n",  __FUNCTION__, offs, val);*/ \
+                  mclose(mfl->mf); exit(2); } /*printf("-D- %s:%d mwrite4: offs = %#x, val = %#x\n",   __FUNCTION__, __LINE__, offs, val);*/ \
                                   } while (0)
 #endif
 
@@ -201,7 +204,9 @@ struct mflash {
 #define CR_FLASH       0xf01a4
 #define ADDR_MSK       0x7ffffUL
 #define CMD_MASK       0xe0000000UL
-#define STATUS_REG_VAL 0x80000000
+
+#define SST_STATUS_REG_VAL   0x80000000
+#define ATMEL_STATUS_REG_VAL 0x0
 
 #define CPUMODE_MSK    0xc0000000UL
 #define CPUMODE_SHIFT  30
@@ -343,7 +348,7 @@ int cntx_st_spi_block_read_ex  (mflash*   mfl,
 
 int cntx_spi_get_type(mflash* mfl, u_int8_t op_type, u_int8_t *vendor, u_int8_t *type, u_int8_t *capacity);
 
-int cntx_sst_spi_write_status_reg(mflash* mfl);
+int cntx_spi_write_status_reg(mflash* mfl, u_int32_t status_reg);
 
 int spi_get_num_of_flashes(int prev_num_of_flashes);
 
@@ -1099,12 +1104,14 @@ typedef struct flash_info {
 
 #define SST_FLASH_NAME   "SST25VFxx"
 #define WINBOND_NAME     "W25QxxBV"
+#define ATMEL_NAME       "AT25DFxxx"
 #define FMT_ST_M25P_NAME
 
 typedef enum flash_vendor {
     FV_ST      = 0x20,
     FV_SST     = 0xbf,
     FV_WINBOND = 0xef,
+    FV_ATMEL   = 0x1f,
 } flash_vendor_t;
 
 typedef enum flash_memory_type {
@@ -1112,6 +1119,7 @@ typedef enum flash_memory_type {
     FMT_ST_M25PX = 0x71,
     FMT_SST_25   = 0x25,
     FMT_WINBOND  = 0x40,
+    FMT_ATMEL    = 0x2,
 
 } flash_memory_type;
 
@@ -1121,7 +1129,7 @@ flash_info_t g_flash_info_arr[] =
         {"M25Pxx",       FV_ST,      FMT_ST_M25P,  MCS_STSPI,  SFC_SE, 0x10000},
         {SST_FLASH_NAME, FV_SST,     FMT_SST_25,   MCS_SSTSPI, SFC_SE, 0x10000},
         {WINBOND_NAME,   FV_WINBOND, FMT_WINBOND,  MCS_STSPI,  SFC_SSE, 0x1000},
-
+        {ATMEL_NAME,     FV_ATMEL,   FMT_ATMEL,    MCS_STSPI,  SFC_SSE, 0x1000},
 };
 
 int cntx_sst_get_log2size(u_int8_t capacity, int* log2spi_size)
@@ -1339,10 +1347,11 @@ int get_flash_params(mflash* mfl, flash_params_t *flash_params, unsigned *type_i
             } else {
                 rc = compare_flash_params(flash_params, spi_sel, type_name, log2size); CHECK_RC(rc);
             }
-
             // Init SST flash.
             if (flash_info->vendor ==  FV_SST && flash_info->type == FMT_SST_25) {
-                rc = cntx_sst_spi_write_status_reg(mfl); CHECK_RC(rc);
+                rc = cntx_spi_write_status_reg(mfl, SST_STATUS_REG_VAL); CHECK_RC(rc);
+            } else if (flash_info->vendor ==  FV_ATMEL && flash_info->type == FMT_ATMEL) {
+                rc = cntx_spi_write_status_reg(mfl, ATMEL_STATUS_REG_VAL); CHECK_RC(rc);
             }
 
             flash_params->num_of_flashes++;
@@ -1945,6 +1954,7 @@ int cntx_exec_cmd(mflash* mfl, u_int32_t gw_cmd, char* msg) {
     gw_cmd = MERGE(gw_cmd,              1, HBO_FLASH_ENABLE,               1);
     gw_cmd = MERGE(gw_cmd, (u_int32_t)mfl->curr_bank,
                                            HBO_CHIP_SELECT,  HBS_CHIP_SELECT);
+    // printf("-D- cntx_exec_cmd: %s\n", msg);
     MWRITE4(CR_FLASH_GW,   gw_cmd);
     return ih3lx_wait_ready(mfl, msg);
 }
@@ -2001,11 +2011,44 @@ int cntx_st_spi_get_status(mflash* mfl, u_int8_t op_type, u_int8_t* status) {
     return MFE_OK;
 }
 
+int get_flash_info_for_atmel(u_int32_t jededc_id, u_int8_t* type, u_int8_t* capacity)
+{
+    u_int8_t tmp_cap;
+
+    tmp_cap = EXTRACT(jededc_id, 8, 5);
+    *type   = EXTRACT(jededc_id, 13, 3);
+    switch (tmp_cap) {
+        case 0x4:
+            *capacity = 0x13;
+            break;
+        case 0x5:
+            *capacity = 0x14;
+            break;
+        case 0x6:
+            *capacity = 0x15;
+            break;
+        case 0x7:
+            *capacity = 0x16;
+            break;
+        default:
+            return MFE_UNSUPPORTED_FLASH_TOPOLOGY;
+    }
+
+    return MFE_OK;
+
+}
 int get_info_from_jededc_id(u_int32_t jededc_id, u_int8_t *vendor, u_int8_t* type, u_int8_t* capacity)
 {
+    int rc;
+
     *vendor   = EXTRACT(jededc_id, 0, 8);
-    *type     = EXTRACT(jededc_id, 8, 8);
-    *capacity = EXTRACT(jededc_id, 16, 8);
+    if (*vendor == FV_ATMEL) {
+        rc = get_flash_info_for_atmel(jededc_id, type, capacity); CHECK_RC(rc);
+    } else {
+        *type     = EXTRACT(jededc_id, 8, 8);
+        *capacity = EXTRACT(jededc_id, 16, 8);
+    }
+
     return MFE_OK;
 }
 
@@ -2015,12 +2058,13 @@ int cntx_spi_get_type(mflash* mfl, u_int8_t op_type, u_int8_t *vendor, u_int8_t*
 
     rc = cntx_int_spi_get_status_data(mfl, op_type, &flash_data, 3); CHECK_RC(rc);
     flash_data = __be32_to_cpu(flash_data);
-
+    // printf("-D- flash_data = %#x\n", flash_data);
     // Get type and some other info from jededc_id
     get_info_from_jededc_id(flash_data, vendor, type, capacity);
+    // printf("-D- cntx_spi_get_type: vendor = %#x, type = %#x, capacity = %#x\n", *vendor, *type, *capacity);
     return MFE_OK;
 }
-int cntx_sst_spi_write_status_reg(mflash* mfl)
+int cntx_spi_write_status_reg(mflash* mfl, u_int32_t status_reg)
 {
     int rc;
     u_int32_t gw_cmd = 0;
@@ -2032,7 +2076,7 @@ int cntx_sst_spi_write_status_reg(mflash* mfl)
 
     gw_cmd = MERGE(gw_cmd, SFC_WRSR, HBO_CMD,        HBS_CMD);
 
-    MWRITE4(HCR_FLASH_DATA, STATUS_REG_VAL);
+    MWRITE4(HCR_FLASH_DATA, status_reg);
     return cntx_exec_cmd(mfl, gw_cmd, "Write-Status-Register");
 }
 
@@ -3079,7 +3123,7 @@ int     mf_sw_reset     (mflash* mfl) {
     if (msw_reset(mfl->mf)) {
         if (errno == EPERM) {
             return MFE_CMD_SUPPORTED_INBAND_ONLY;
-        } else if (errno == EOPNOTSUPP) {
+        } else if (errno == OP_NOT_SUPPORTED) {
             return MFE_MANAGED_SWITCH_NOT_SUPPORTED;
         } else {
 
index 307b5fd81e214a07099613a91730a4049f3cbdbc..b1f665788a3aa509a497fb128d9cffa546c23b9f 100644 (file)
@@ -46,7 +46,7 @@
 #endif
 
 #ifndef MFT_VERSION_STR
-    #define MFT_VERSION_STR "mft 2.7.0-20"
+    #define MFT_VERSION_STR "mft 2.7.1-7"
 #endif
 
 static inline