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(typeof(*((struct rtl_fw_phy_action *)0)->code)) 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 regno = (action & 0x0fff0000) >> 16; 96 97 switch (action >> 28) { 98 case PHY_READ: 99 case PHY_DATA_OR: 100 case PHY_DATA_AND: 101 case PHY_MDIO_CHG: 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_BJMPN: 109 if (regno > index) 110 goto out; 111 break; 112 case PHY_READCOUNT_EQ_SKIP: 113 if (index + 2 >= pa->size) 114 goto out; 115 break; 116 case PHY_COMP_EQ_SKIPN: 117 case PHY_COMP_NEQ_SKIPN: 118 case PHY_SKIPN: 119 if (index + 1 + regno >= pa->size) 120 goto out; 121 break; 122 123 default: 124 dev_err(rtl_fw->dev, "Invalid action 0x%08x\n", action); 125 return false; 126 } 127 } 128 129 return true; 130 out: 131 dev_err(rtl_fw->dev, "Out of range of firmware\n"); 132 return false; 133 } 134 135 void rtl_fw_write_firmware(struct rtl8169_private *tp, struct rtl_fw *rtl_fw) 136 { 137 struct rtl_fw_phy_action *pa = &rtl_fw->phy_action; 138 rtl_fw_write_t fw_write = rtl_fw->phy_write; 139 rtl_fw_read_t fw_read = rtl_fw->phy_read; 140 int predata = 0, count = 0; 141 size_t index; 142 143 for (index = 0; index < pa->size; index++) { 144 u32 action = le32_to_cpu(pa->code[index]); 145 u32 data = action & 0x0000ffff; 146 u32 regno = (action & 0x0fff0000) >> 16; 147 enum rtl_fw_opcode opcode = action >> 28; 148 149 if (!action) 150 break; 151 152 switch (opcode) { 153 case PHY_READ: 154 predata = fw_read(tp, regno); 155 count++; 156 break; 157 case PHY_DATA_OR: 158 predata |= data; 159 break; 160 case PHY_DATA_AND: 161 predata &= data; 162 break; 163 case PHY_BJMPN: 164 index -= (regno + 1); 165 break; 166 case PHY_MDIO_CHG: 167 if (data == 0) { 168 fw_write = rtl_fw->phy_write; 169 fw_read = rtl_fw->phy_read; 170 } else if (data == 1) { 171 fw_write = rtl_fw->mac_mcu_write; 172 fw_read = rtl_fw->mac_mcu_read; 173 } 174 175 break; 176 case PHY_CLEAR_READCOUNT: 177 count = 0; 178 break; 179 case PHY_WRITE: 180 fw_write(tp, regno, data); 181 break; 182 case PHY_READCOUNT_EQ_SKIP: 183 if (count == data) 184 index++; 185 break; 186 case PHY_COMP_EQ_SKIPN: 187 if (predata == data) 188 index += regno; 189 break; 190 case PHY_COMP_NEQ_SKIPN: 191 if (predata != data) 192 index += regno; 193 break; 194 case PHY_WRITE_PREVIOUS: 195 fw_write(tp, regno, predata); 196 break; 197 case PHY_SKIPN: 198 index += regno; 199 break; 200 case PHY_DELAY_MS: 201 mdelay(data); 202 break; 203 } 204 } 205 } 206 207 void rtl_fw_release_firmware(struct rtl_fw *rtl_fw) 208 { 209 release_firmware(rtl_fw->fw); 210 } 211 212 int rtl_fw_request_firmware(struct rtl_fw *rtl_fw) 213 { 214 int rc; 215 216 rc = request_firmware(&rtl_fw->fw, rtl_fw->fw_name, rtl_fw->dev); 217 if (rc < 0) 218 goto out; 219 220 if (!rtl_fw_format_ok(rtl_fw) || !rtl_fw_data_ok(rtl_fw)) { 221 release_firmware(rtl_fw->fw); 222 rc = -EINVAL; 223 goto out; 224 } 225 226 return 0; 227 out: 228 dev_err(rtl_fw->dev, "Unable to load firmware %s (%d)\n", 229 rtl_fw->fw_name, rc); 230 return rc; 231 } 232