diff options
Diffstat (limited to 'drivers/net/ks8851.c')
-rw-r--r-- | drivers/net/ks8851.c | 366 |
1 files changed, 361 insertions, 5 deletions
diff --git a/drivers/net/ks8851.c b/drivers/net/ks8851.c index 4dcd61f81ec2..b4fb07a6f13f 100644 --- a/drivers/net/ks8851.c +++ b/drivers/net/ks8851.c | |||
@@ -78,7 +78,9 @@ union ks8851_tx_hdr { | |||
78 | * @msg_enable: The message flags controlling driver output (see ethtool). | 78 | * @msg_enable: The message flags controlling driver output (see ethtool). |
79 | * @fid: Incrementing frame id tag. | 79 | * @fid: Incrementing frame id tag. |
80 | * @rc_ier: Cached copy of KS_IER. | 80 | * @rc_ier: Cached copy of KS_IER. |
81 | * @rc_ccr: Cached copy of KS_CCR. | ||
81 | * @rc_rxqcr: Cached copy of KS_RXQCR. | 82 | * @rc_rxqcr: Cached copy of KS_RXQCR. |
83 | * @eeprom_size: Companion eeprom size in Bytes, 0 if no eeprom | ||
82 | * | 84 | * |
83 | * The @lock ensures that the chip is protected when certain operations are | 85 | * The @lock ensures that the chip is protected when certain operations are |
84 | * in progress. When the read or write packet transfer is in progress, most | 86 | * in progress. When the read or write packet transfer is in progress, most |
@@ -109,6 +111,8 @@ struct ks8851_net { | |||
109 | 111 | ||
110 | u16 rc_ier; | 112 | u16 rc_ier; |
111 | u16 rc_rxqcr; | 113 | u16 rc_rxqcr; |
114 | u16 rc_ccr; | ||
115 | u16 eeprom_size; | ||
112 | 116 | ||
113 | struct mii_if_info mii; | 117 | struct mii_if_info mii; |
114 | struct ks8851_rxctrl rxctrl; | 118 | struct ks8851_rxctrl rxctrl; |
@@ -717,12 +721,14 @@ static void ks8851_tx_work(struct work_struct *work) | |||
717 | txb = skb_dequeue(&ks->txq); | 721 | txb = skb_dequeue(&ks->txq); |
718 | last = skb_queue_empty(&ks->txq); | 722 | last = skb_queue_empty(&ks->txq); |
719 | 723 | ||
720 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); | 724 | if (txb != NULL) { |
721 | ks8851_wrpkt(ks, txb, last); | 725 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr | RXQCR_SDA); |
722 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); | 726 | ks8851_wrpkt(ks, txb, last); |
723 | ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE); | 727 | ks8851_wrreg16(ks, KS_RXQCR, ks->rc_rxqcr); |
728 | ks8851_wrreg16(ks, KS_TXQCR, TXQCR_METFE); | ||
724 | 729 | ||
725 | ks8851_done_tx(ks, txb); | 730 | ks8851_done_tx(ks, txb); |
731 | } | ||
726 | } | 732 | } |
727 | 733 | ||
728 | mutex_unlock(&ks->lock); | 734 | mutex_unlock(&ks->lock); |
@@ -1028,6 +1034,234 @@ static const struct net_device_ops ks8851_netdev_ops = { | |||
1028 | .ndo_validate_addr = eth_validate_addr, | 1034 | .ndo_validate_addr = eth_validate_addr, |
1029 | }; | 1035 | }; |
1030 | 1036 | ||
1037 | /* Companion eeprom access */ | ||
1038 | |||
1039 | enum { /* EEPROM programming states */ | ||
1040 | EEPROM_CONTROL, | ||
1041 | EEPROM_ADDRESS, | ||
1042 | EEPROM_DATA, | ||
1043 | EEPROM_COMPLETE | ||
1044 | }; | ||
1045 | |||
1046 | /** | ||
1047 | * ks8851_eeprom_read - read a 16bits word in ks8851 companion EEPROM | ||
1048 | * @dev: The network device the PHY is on. | ||
1049 | * @addr: EEPROM address to read | ||
1050 | * | ||
1051 | * eeprom_size: used to define the data coding length. Can be changed | ||
1052 | * through debug-fs. | ||
1053 | * | ||
1054 | * Programs a read on the EEPROM using ks8851 EEPROM SW access feature. | ||
1055 | * Warning: The READ feature is not supported on ks8851 revision 0. | ||
1056 | * | ||
1057 | * Rough programming model: | ||
1058 | * - on period start: set clock high and read value on bus | ||
1059 | * - on period / 2: set clock low and program value on bus | ||
1060 | * - start on period / 2 | ||
1061 | */ | ||
1062 | unsigned int ks8851_eeprom_read(struct net_device *dev, unsigned int addr) | ||
1063 | { | ||
1064 | struct ks8851_net *ks = netdev_priv(dev); | ||
1065 | int eepcr; | ||
1066 | int ctrl = EEPROM_OP_READ; | ||
1067 | int state = EEPROM_CONTROL; | ||
1068 | int bit_count = EEPROM_OP_LEN - 1; | ||
1069 | unsigned int data = 0; | ||
1070 | int dummy; | ||
1071 | unsigned int addr_len; | ||
1072 | |||
1073 | addr_len = (ks->eeprom_size == 128) ? 6 : 8; | ||
1074 | |||
1075 | /* start transaction: chip select high, authorize write */ | ||
1076 | mutex_lock(&ks->lock); | ||
1077 | eepcr = EEPCR_EESA | EEPCR_EESRWA; | ||
1078 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1079 | eepcr |= EEPCR_EECS; | ||
1080 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1081 | mutex_unlock(&ks->lock); | ||
1082 | |||
1083 | while (state != EEPROM_COMPLETE) { | ||
1084 | /* falling clock period starts... */ | ||
1085 | /* set EED_IO pin for control and address */ | ||
1086 | eepcr &= ~EEPCR_EEDO; | ||
1087 | switch (state) { | ||
1088 | case EEPROM_CONTROL: | ||
1089 | eepcr |= ((ctrl >> bit_count) & 1) << 2; | ||
1090 | if (bit_count-- <= 0) { | ||
1091 | bit_count = addr_len - 1; | ||
1092 | state = EEPROM_ADDRESS; | ||
1093 | } | ||
1094 | break; | ||
1095 | case EEPROM_ADDRESS: | ||
1096 | eepcr |= ((addr >> bit_count) & 1) << 2; | ||
1097 | bit_count--; | ||
1098 | break; | ||
1099 | case EEPROM_DATA: | ||
1100 | /* Change to receive mode */ | ||
1101 | eepcr &= ~EEPCR_EESRWA; | ||
1102 | break; | ||
1103 | } | ||
1104 | |||
1105 | /* lower clock */ | ||
1106 | eepcr &= ~EEPCR_EESCK; | ||
1107 | |||
1108 | mutex_lock(&ks->lock); | ||
1109 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1110 | mutex_unlock(&ks->lock); | ||
1111 | |||
1112 | /* waitread period / 2 */ | ||
1113 | udelay(EEPROM_SK_PERIOD / 2); | ||
1114 | |||
1115 | /* rising clock period starts... */ | ||
1116 | |||
1117 | /* raise clock */ | ||
1118 | mutex_lock(&ks->lock); | ||
1119 | eepcr |= EEPCR_EESCK; | ||
1120 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1121 | mutex_unlock(&ks->lock); | ||
1122 | |||
1123 | /* Manage read */ | ||
1124 | switch (state) { | ||
1125 | case EEPROM_ADDRESS: | ||
1126 | if (bit_count < 0) { | ||
1127 | bit_count = EEPROM_DATA_LEN - 1; | ||
1128 | state = EEPROM_DATA; | ||
1129 | } | ||
1130 | break; | ||
1131 | case EEPROM_DATA: | ||
1132 | mutex_lock(&ks->lock); | ||
1133 | dummy = ks8851_rdreg16(ks, KS_EEPCR); | ||
1134 | mutex_unlock(&ks->lock); | ||
1135 | data |= ((dummy >> EEPCR_EESB_OFFSET) & 1) << bit_count; | ||
1136 | if (bit_count-- <= 0) | ||
1137 | state = EEPROM_COMPLETE; | ||
1138 | break; | ||
1139 | } | ||
1140 | |||
1141 | /* wait period / 2 */ | ||
1142 | udelay(EEPROM_SK_PERIOD / 2); | ||
1143 | } | ||
1144 | |||
1145 | /* close transaction */ | ||
1146 | mutex_lock(&ks->lock); | ||
1147 | eepcr &= ~EEPCR_EECS; | ||
1148 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1149 | eepcr = 0; | ||
1150 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1151 | mutex_unlock(&ks->lock); | ||
1152 | |||
1153 | return data; | ||
1154 | } | ||
1155 | |||
1156 | /** | ||
1157 | * ks8851_eeprom_write - write a 16bits word in ks8851 companion EEPROM | ||
1158 | * @dev: The network device the PHY is on. | ||
1159 | * @op: operand (can be WRITE, EWEN, EWDS) | ||
1160 | * @addr: EEPROM address to write | ||
1161 | * @data: data to write | ||
1162 | * | ||
1163 | * eeprom_size: used to define the data coding length. Can be changed | ||
1164 | * through debug-fs. | ||
1165 | * | ||
1166 | * Programs a write on the EEPROM using ks8851 EEPROM SW access feature. | ||
1167 | * | ||
1168 | * Note that a write enable is required before writing data. | ||
1169 | * | ||
1170 | * Rough programming model: | ||
1171 | * - on period start: set clock high | ||
1172 | * - on period / 2: set clock low and program value on bus | ||
1173 | * - start on period / 2 | ||
1174 | */ | ||
1175 | void ks8851_eeprom_write(struct net_device *dev, unsigned int op, | ||
1176 | unsigned int addr, unsigned int data) | ||
1177 | { | ||
1178 | struct ks8851_net *ks = netdev_priv(dev); | ||
1179 | int eepcr; | ||
1180 | int state = EEPROM_CONTROL; | ||
1181 | int bit_count = EEPROM_OP_LEN - 1; | ||
1182 | unsigned int addr_len; | ||
1183 | |||
1184 | addr_len = (ks->eeprom_size == 128) ? 6 : 8; | ||
1185 | |||
1186 | switch (op) { | ||
1187 | case EEPROM_OP_EWEN: | ||
1188 | addr = 0x30; | ||
1189 | break; | ||
1190 | case EEPROM_OP_EWDS: | ||
1191 | addr = 0; | ||
1192 | break; | ||
1193 | } | ||
1194 | |||
1195 | /* start transaction: chip select high, authorize write */ | ||
1196 | mutex_lock(&ks->lock); | ||
1197 | eepcr = EEPCR_EESA | EEPCR_EESRWA; | ||
1198 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1199 | eepcr |= EEPCR_EECS; | ||
1200 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1201 | mutex_unlock(&ks->lock); | ||
1202 | |||
1203 | while (state != EEPROM_COMPLETE) { | ||
1204 | /* falling clock period starts... */ | ||
1205 | /* set EED_IO pin for control and address */ | ||
1206 | eepcr &= ~EEPCR_EEDO; | ||
1207 | switch (state) { | ||
1208 | case EEPROM_CONTROL: | ||
1209 | eepcr |= ((op >> bit_count) & 1) << 2; | ||
1210 | if (bit_count-- <= 0) { | ||
1211 | bit_count = addr_len - 1; | ||
1212 | state = EEPROM_ADDRESS; | ||
1213 | } | ||
1214 | break; | ||
1215 | case EEPROM_ADDRESS: | ||
1216 | eepcr |= ((addr >> bit_count) & 1) << 2; | ||
1217 | if (bit_count-- <= 0) { | ||
1218 | if (op == EEPROM_OP_WRITE) { | ||
1219 | bit_count = EEPROM_DATA_LEN - 1; | ||
1220 | state = EEPROM_DATA; | ||
1221 | } else { | ||
1222 | state = EEPROM_COMPLETE; | ||
1223 | } | ||
1224 | } | ||
1225 | break; | ||
1226 | case EEPROM_DATA: | ||
1227 | eepcr |= ((data >> bit_count) & 1) << 2; | ||
1228 | if (bit_count-- <= 0) | ||
1229 | state = EEPROM_COMPLETE; | ||
1230 | break; | ||
1231 | } | ||
1232 | |||
1233 | /* lower clock */ | ||
1234 | eepcr &= ~EEPCR_EESCK; | ||
1235 | |||
1236 | mutex_lock(&ks->lock); | ||
1237 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1238 | mutex_unlock(&ks->lock); | ||
1239 | |||
1240 | /* wait period / 2 */ | ||
1241 | udelay(EEPROM_SK_PERIOD / 2); | ||
1242 | |||
1243 | /* rising clock period starts... */ | ||
1244 | |||
1245 | /* raise clock */ | ||
1246 | eepcr |= EEPCR_EESCK; | ||
1247 | mutex_lock(&ks->lock); | ||
1248 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1249 | mutex_unlock(&ks->lock); | ||
1250 | |||
1251 | /* wait period / 2 */ | ||
1252 | udelay(EEPROM_SK_PERIOD / 2); | ||
1253 | } | ||
1254 | |||
1255 | /* close transaction */ | ||
1256 | mutex_lock(&ks->lock); | ||
1257 | eepcr &= ~EEPCR_EECS; | ||
1258 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1259 | eepcr = 0; | ||
1260 | ks8851_wrreg16(ks, KS_EEPCR, eepcr); | ||
1261 | mutex_unlock(&ks->lock); | ||
1262 | |||
1263 | } | ||
1264 | |||
1031 | /* ethtool support */ | 1265 | /* ethtool support */ |
1032 | 1266 | ||
1033 | static void ks8851_get_drvinfo(struct net_device *dev, | 1267 | static void ks8851_get_drvinfo(struct net_device *dev, |
@@ -1074,6 +1308,117 @@ static int ks8851_nway_reset(struct net_device *dev) | |||
1074 | return mii_nway_restart(&ks->mii); | 1308 | return mii_nway_restart(&ks->mii); |
1075 | } | 1309 | } |
1076 | 1310 | ||
1311 | static int ks8851_get_eeprom_len(struct net_device *dev) | ||
1312 | { | ||
1313 | struct ks8851_net *ks = netdev_priv(dev); | ||
1314 | return ks->eeprom_size; | ||
1315 | } | ||
1316 | |||
1317 | static int ks8851_get_eeprom(struct net_device *dev, | ||
1318 | struct ethtool_eeprom *eeprom, u8 *bytes) | ||
1319 | { | ||
1320 | struct ks8851_net *ks = netdev_priv(dev); | ||
1321 | u16 *eeprom_buff; | ||
1322 | int first_word; | ||
1323 | int last_word; | ||
1324 | int ret_val = 0; | ||
1325 | u16 i; | ||
1326 | |||
1327 | if (eeprom->len == 0) | ||
1328 | return -EINVAL; | ||
1329 | |||
1330 | if (eeprom->len > ks->eeprom_size) | ||
1331 | return -EINVAL; | ||
1332 | |||
1333 | eeprom->magic = ks8851_rdreg16(ks, KS_CIDER); | ||
1334 | |||
1335 | first_word = eeprom->offset >> 1; | ||
1336 | last_word = (eeprom->offset + eeprom->len - 1) >> 1; | ||
1337 | |||
1338 | eeprom_buff = kmalloc(sizeof(u16) * | ||
1339 | (last_word - first_word + 1), GFP_KERNEL); | ||
1340 | if (!eeprom_buff) | ||
1341 | return -ENOMEM; | ||
1342 | |||
1343 | for (i = 0; i < last_word - first_word + 1; i++) | ||
1344 | eeprom_buff[i] = ks8851_eeprom_read(dev, first_word + 1); | ||
1345 | |||
1346 | /* Device's eeprom is little-endian, word addressable */ | ||
1347 | for (i = 0; i < last_word - first_word + 1; i++) | ||
1348 | le16_to_cpus(&eeprom_buff[i]); | ||
1349 | |||
1350 | memcpy(bytes, (u8 *)eeprom_buff + (eeprom->offset & 1), eeprom->len); | ||
1351 | kfree(eeprom_buff); | ||
1352 | |||
1353 | return ret_val; | ||
1354 | } | ||
1355 | |||
1356 | static int ks8851_set_eeprom(struct net_device *dev, | ||
1357 | struct ethtool_eeprom *eeprom, u8 *bytes) | ||
1358 | { | ||
1359 | struct ks8851_net *ks = netdev_priv(dev); | ||
1360 | u16 *eeprom_buff; | ||
1361 | void *ptr; | ||
1362 | int max_len; | ||
1363 | int first_word; | ||
1364 | int last_word; | ||
1365 | int ret_val = 0; | ||
1366 | u16 i; | ||
1367 | |||
1368 | if (eeprom->len == 0) | ||
1369 | return -EOPNOTSUPP; | ||
1370 | |||
1371 | if (eeprom->len > ks->eeprom_size) | ||
1372 | return -EINVAL; | ||
1373 | |||
1374 | if (eeprom->magic != ks8851_rdreg16(ks, KS_CIDER)) | ||
1375 | return -EFAULT; | ||
1376 | |||
1377 | first_word = eeprom->offset >> 1; | ||
1378 | last_word = (eeprom->offset + eeprom->len - 1) >> 1; | ||
1379 | max_len = (last_word - first_word + 1) * 2; | ||
1380 | eeprom_buff = kmalloc(max_len, GFP_KERNEL); | ||
1381 | if (!eeprom_buff) | ||
1382 | return -ENOMEM; | ||
1383 | |||
1384 | ptr = (void *)eeprom_buff; | ||
1385 | |||
1386 | if (eeprom->offset & 1) { | ||
1387 | /* need read/modify/write of first changed EEPROM word */ | ||
1388 | /* only the second byte of the word is being modified */ | ||
1389 | eeprom_buff[0] = ks8851_eeprom_read(dev, first_word); | ||
1390 | ptr++; | ||
1391 | } | ||
1392 | if ((eeprom->offset + eeprom->len) & 1) | ||
1393 | /* need read/modify/write of last changed EEPROM word */ | ||
1394 | /* only the first byte of the word is being modified */ | ||
1395 | eeprom_buff[last_word - first_word] = | ||
1396 | ks8851_eeprom_read(dev, last_word); | ||
1397 | |||
1398 | |||
1399 | /* Device's eeprom is little-endian, word addressable */ | ||
1400 | le16_to_cpus(&eeprom_buff[0]); | ||
1401 | le16_to_cpus(&eeprom_buff[last_word - first_word]); | ||
1402 | |||
1403 | memcpy(ptr, bytes, eeprom->len); | ||
1404 | |||
1405 | for (i = 0; i < last_word - first_word + 1; i++) | ||
1406 | eeprom_buff[i] = cpu_to_le16(eeprom_buff[i]); | ||
1407 | |||
1408 | ks8851_eeprom_write(dev, EEPROM_OP_EWEN, 0, 0); | ||
1409 | |||
1410 | for (i = 0; i < last_word - first_word + 1; i++) { | ||
1411 | ks8851_eeprom_write(dev, EEPROM_OP_WRITE, first_word + i, | ||
1412 | eeprom_buff[i]); | ||
1413 | mdelay(EEPROM_WRITE_TIME); | ||
1414 | } | ||
1415 | |||
1416 | ks8851_eeprom_write(dev, EEPROM_OP_EWDS, 0, 0); | ||
1417 | |||
1418 | kfree(eeprom_buff); | ||
1419 | return ret_val; | ||
1420 | } | ||
1421 | |||
1077 | static const struct ethtool_ops ks8851_ethtool_ops = { | 1422 | static const struct ethtool_ops ks8851_ethtool_ops = { |
1078 | .get_drvinfo = ks8851_get_drvinfo, | 1423 | .get_drvinfo = ks8851_get_drvinfo, |
1079 | .get_msglevel = ks8851_get_msglevel, | 1424 | .get_msglevel = ks8851_get_msglevel, |
@@ -1082,6 +1427,9 @@ static const struct ethtool_ops ks8851_ethtool_ops = { | |||
1082 | .set_settings = ks8851_set_settings, | 1427 | .set_settings = ks8851_set_settings, |
1083 | .get_link = ks8851_get_link, | 1428 | .get_link = ks8851_get_link, |
1084 | .nway_reset = ks8851_nway_reset, | 1429 | .nway_reset = ks8851_nway_reset, |
1430 | .get_eeprom_len = ks8851_get_eeprom_len, | ||
1431 | .get_eeprom = ks8851_get_eeprom, | ||
1432 | .set_eeprom = ks8851_set_eeprom, | ||
1085 | }; | 1433 | }; |
1086 | 1434 | ||
1087 | /* MII interface controls */ | 1435 | /* MII interface controls */ |
@@ -1267,6 +1615,14 @@ static int __devinit ks8851_probe(struct spi_device *spi) | |||
1267 | goto err_id; | 1615 | goto err_id; |
1268 | } | 1616 | } |
1269 | 1617 | ||
1618 | /* cache the contents of the CCR register for EEPROM, etc. */ | ||
1619 | ks->rc_ccr = ks8851_rdreg16(ks, KS_CCR); | ||
1620 | |||
1621 | if (ks->rc_ccr & CCR_EEPROM) | ||
1622 | ks->eeprom_size = 128; | ||
1623 | else | ||
1624 | ks->eeprom_size = 0; | ||
1625 | |||
1270 | ks8851_read_selftest(ks); | 1626 | ks8851_read_selftest(ks); |
1271 | ks8851_init_mac(ks); | 1627 | ks8851_init_mac(ks); |
1272 | 1628 | ||