1 // SPDX-License-Identifier: GPL-2.0-only 2 /* r8169_firmware.c: RealTek 8169/8168/8101 ethernet driver. 3 * 4 * Copyright (c) 2002 ShuChen <shuchen@realtek.com.tw> 5 * Copyright (c) 2003 - 2007 Francois Romieu <romieu@fr.zoreil.com> 6 * Copyright (c) a lot of people too. Please respect their work. 7 * 8 * See MAINTAINERS file for support contact information. 9 */ 10 11 #include <linux/delay.h> 12 #include <linux/firmware.h> 13 14 #include "r8169_firmware.h" 15 16 enum rtl_fw_opcode { 17 PHY_READ = 0x0, 18 PHY_DATA_OR = 0x1, 19 PHY_DATA_AND = 0x2, 20 PHY_BJMPN = 0x3, 21 PHY_MDIO_CHG = 0x4, 22 PHY_CLEAR_READCOUNT = 0x7, 23 PHY_WRITE = 0x8, 24 PHY_READCOUNT_EQ_SKIP = 0x9, 25 PHY_COMP_EQ_SKIPN = 0xa, 26 PHY_COMP_NEQ_SKIPN = 0xb, 27 PHY_WRITE_PREVIOUS = 0xc, 28 PHY_SKIPN = 0xd, 29 PHY_DELAY_MS = 0xe, 30 }; 31 32 struct fw_info { 33 u32 magic; 34 char version[RTL_VER_SIZE]; 35 __le32 fw_start; 36 __le32 fw_len; 37 u8 chksum; 38 } __packed; 39 40 #define FW_OPCODE_SIZE sizeof_field(struct rtl_fw_phy_action, code[0]) 41 42 static bool rtl_fw_format_ok(struct rtl_fw *rtl_fw) 43 { 44 const struct firmware *fw = rtl_fw->fw; 45 struct fw_info *fw_info = (struct fw_info *)fw->data; 46 struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; 47 48 if (fw->size < FW_OPCODE_SIZE) 49 return false; 50 51 if (!fw_info->magic) { 52 size_t i, size, start; 53 u8 checksum = 0; 54 55 if (fw->size < sizeof(*fw_info)) 56 return false; 57 58 for (i = 0; i < fw->size; i++) 59 checksum += fw->data[i]; 60 if (checksum != 0) 61 return false; 62 63 start = le32_to_cpu(fw_info->fw_start); 64 if (start > fw->size) 65 return false; 66 67 size = le32_to_cpu(fw_info->fw_len); 68 if (size > (fw->size - start) / FW_OPCODE_SIZE) 69 return false; 70 71 strscpy(rtl_fw->version, fw_info->version, RTL_VER_SIZE); 72 73 pa->code = (__le32 *)(fw->data + start); 74 pa->size = size; 75 } else { 76 if (fw->size % FW_OPCODE_SIZE) 77 return false; 78 79 strscpy(rtl_fw->version, rtl_fw->fw_name, RTL_VER_SIZE); 80 81 pa->code = (__le32 *)fw->data; 82 pa->size = fw->size / FW_OPCODE_SIZE; 83 } 84 85 return true; 86 } 87 88 static bool rtl_fw_data_ok(struct rtl_fw *rtl_fw) 89 { 90 struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; 91 size_t index; 92 93 for (index = 0; index < pa->size; index++) { 94 u32 action = le32_to_cpu(pa->code[index]); 95 u32 val = action & 0x0000ffff; 96 u32 regno = (action & 0x0fff0000) >> 16; 97 98 switch (action >> 28) { 99 case PHY_READ: 100 case PHY_DATA_OR: 101 case PHY_DATA_AND: 102 case PHY_CLEAR_READCOUNT: 103 case PHY_WRITE: 104 case PHY_WRITE_PREVIOUS: 105 case PHY_DELAY_MS: 106 break; 107 108 case PHY_MDIO_CHG: 109 if (val > 1) 110 goto out; 111 break; 112 113 case PHY_BJMPN: 114 if (regno > index) 115 goto out; 116 break; 117 case PHY_READCOUNT_EQ_SKIP: 118 if (index + 2 >= pa->size) 119 goto out; 120 break; 121 case PHY_COMP_EQ_SKIPN: 122 case PHY_COMP_NEQ_SKIPN: 123 case PHY_SKIPN: 124 if (index + 1 + regno >= pa->size) 125 goto out; 126 break; 127 128 default: 129 dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action); 130 return false; 131 } 132 } 133 134 return true; 135 out: 136 dev_err(rtl_fw->dev, "Out of range of firmware\n"); 137 return false; 138 } 139 140 void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) 141 { 142 struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; 143 rtl_fw_write_t fw_write = rtl_fw->phy_write; 144 rtl_fw_read_t fw_read = rtl_fw->phy_read; 145 int predata = 0, count = 0; 146 size_t index; 147 148 for (index = 0; index < pa->size; index++) { 149 u32 action = le32_to_cpu(pa->code[index]); 150 u32 data = action & 0x0000ffff; 151 u32 regno = (action & 0x0fff0000) >> 16; 152 enum rtl_fw_opcode opcode = action >> 28; 153 154 switch (opcode) { 155 case PHY_READ: 156 predata = fw_read(tp, regno); 157 count++; 158 break; 159 case PHY_DATA_OR: 160 predata |= data; 161 break; 162 case PHY_DATA_AND: 163 predata &= data; 164 break; 165 case PHY_BJMPN: 166 index -= (regno + 1); 167 break; 168 case PHY_MDIO_CHG: 169 if (data) { 170 fw_write = rtl_fw->mac_mcu_write; 171 fw_read = rtl_fw->mac_mcu_read; 172 } else { 173 fw_write = rtl_fw->phy_write; 174 fw_read = rtl_fw->phy_read; 175 } 176 177 break; 178 case PHY_CLEAR_READCOUNT: 179 count = 0; 180 break; 181 case PHY_WRITE: 182 fw_write(tp, regno, data); 183 break; 184 case PHY_READCOUNT_EQ_SKIP: 185 if (count == data) 186 index++; 187 break; 188 case PHY_COMP_EQ_SKIPN: 189 if (predata == data) 190 index += regno; 191 break; 192 case PHY_COMP_NEQ_SKIPN: 193 if (predata != data) 194 index += regno; 195 break; 196 case PHY_WRITE_PREVIOUS: 197 fw_write(tp, regno, predata); 198 break; 199 case PHY_SKIPN: 200 index += regno; 201 break; 202 case PHY_DELAY_MS: 203 msleep(data); 204 break; 205 } 206 } 207 } 208 209 void rtl_fw_release_firmware(struct rtl_fw *rtl_fw) 210 { 211 release_firmware(rtl_fw->fw); 212 } 213 214 int rtl_fw_request_firmware(struct rtl_fw *rtl_fw) 215 { 216 int rc; 217 218 rc = firmware_request_nowarn(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev); 219 if (rc < 0) 220 goto out; 221 222 if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) { 223 release_firmware(rtl_fw->fw); 224 rc = -EINVAL; 225 goto out; 226 } 227 228 return 0; 229 out: 230 dev_warn(rtl_fw->dev, "Unable to load firmware %s (%d)\n", 231 rtl_fw->fw_name, rc); 232 return rc; 233 } 234