Changeset 5
- Timestamp:
- Feb 19, 2008, 5:03:59 PM (17 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
gpxe_study/kernel_2.6.20_src/sis900.c
r4 r5 974 974 /* Equalizer workaround Rule */ 975 975 sis630_set_eq(net_dev, sis_priv->chipset_rev); 976 ret = request_irq(net_dev->irq, &sis900_interrupt, IRQF_SHARED, 977 net_dev->name, net_dev); 976 ret = request_irq(net_dev->irq, &sis900_interrupt, IRQF_SHARED, net_dev->name, net_dev); 978 977 if (ret) 979 978 return ret; 979 980 980 981 981 sis900_init_rxfilter(net_dev); … … 1094 1094 { 1095 1095 u32 rfcrSave; 1096 1097 1098 1096 struct sis900_private *sis_priv = net_dev->priv; 1097 long ioaddr = net_dev->base_addr; 1098 u32 i; 1099 1099 rfcrSave = inl(rfcr + ioaddr); 1100 1100 … … 1130 1130 sis900_init_tx_ring(struct net_device *net_dev) 1131 1131 { 1132 struct sis900_private *sis_priv = net_dev->priv; 1133 long ioaddr = net_dev->base_addr; 1134 int i; 1135 1136 sis_priv->tx_full = 0; 1137 sis_priv->dirty_tx = sis_priv->cur_tx = 0; 1138 1139 for (i = 0; i < NUM_TX_DESC; i++) { 1140 sis_priv->tx_skbuff[i] = NULL; 1141 1142 sis_priv->tx_ring[i].link = sis_priv->tx_ring_dma + 1143 ((i+1)%NUM_TX_DESC)*sizeof(BufferDesc); 1144 sis_priv->tx_ring[i].cmdsts = 0; 1132 struct sis900_private *sis_priv = net_dev->priv; 1133 long ioaddr = net_dev->base_addr; 1134 int i; 1135 sis_priv->tx_full = 0; 1136 sis_priv->dirty_tx = sis_priv->cur_tx = 0; 1137 for (i = 0; i < NUM_TX_DESC; i++) { 1138 sis_priv->tx_skbuff[i] = NULL; 1139 sis_priv->tx_ring[i].link = sis_priv->tx_ring_dma + 1140 ((i+1)%NUM_TX_DESC)*sizeof(BufferDesc); 1141 sis_priv->tx_ring[i].cmdsts = 0; 1145 1142 sis_priv->tx_ring[i].bufptr = 0; 1146 1147 1148 1149 1150 1151 1152 1143 } 1144 1145 /* load Transmit Descriptor Register */ 1146 outl(sis_priv->tx_ring_dma, ioaddr + txdp); 1147 if (netif_msg_hw(sis_priv)) 1148 printk(KERN_DEBUG "%s: TX descriptor register loaded with: %8.8x\n", 1149 net_dev->name, inl(ioaddr + txdp)); 1153 1150 } 1154 1151 … … 1206 1203 printk(KERN_DEBUG "%s: RX descriptor register loaded with: %8.8x\n", 1207 1204 net_dev->name, inl(ioaddr + rxdp)); 1205 } 1206 1207 /** 1208 * set_rx_mode - Set SiS900 receive mode 1209 * @net_dev: the net device to be set 1210 * 1211 * Set SiS900 receive mode for promiscuous, multicast, or broadcast mode. 1212 * And set the appropriate multicast filter. 1213 * Multicast hash table changes from 128 to 256 bits for 635M/B & 900B0. 1214 */ 1215 1216 static void set_rx_mode(struct net_device *net_dev) 1217 { 1218 int i, table_entries; 1219 u32 rx_mode; 1220 long ioaddr = net_dev->base_addr; 1221 struct sis900_private * sis_priv = net_dev->priv; 1222 u16 mc_filter[16] = {0}; /* 256/128 bits multicast hash table */ 1223 /* 635 Hash Table entries = 256(2^16) */ 1224 1225 if((sis_priv->chipset_rev >= SIS635A_900_REV) || (sis_priv->chipset_rev == SIS900B_900_REV)) 1226 table_entries = 16; 1227 else 1228 table_entries = 8; 1229 if (net_dev->flags & IFF_PROMISC) { 1230 /* Accept any kinds of packets */ 1231 rx_mode = RFPromiscuous; 1232 for (i = 0; i < table_entries; i++) 1233 mc_filter[i] = 0xffff; 1234 } else if ((net_dev->mc_count > multicast_filter_limit) || (net_dev->flags & IFF_ALLMULTI)) { 1235 1236 /* too many multicast addresses or accept all multicast packet */ 1237 rx_mode = RFAAB | RFAAM; 1238 for (i = 0; i < table_entries; i++) 1239 mc_filter[i] = 0xffff; 1240 1241 } else { 1242 /* Accept Broadcast packet, destination address matchs our 1243 * MAC address, use Receive Filter to reject unwanted MCAST 1244 * packets */ 1245 struct dev_mc_list *mclist; 1246 rx_mode = RFAAB; 1247 for (i = 0, mclist = net_dev->mc_list; 1248 mclist && i < net_dev->mc_count; 1249 i++, mclist = mclist->next) { 1250 unsigned int bit_nr = sis900_mcast_bitnr(mclist->dmi_addr, sis_priv->chipset_rev); 1251 mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf)); 1252 } 1253 } 1254 /* update Multicast Hash Table in Receive Filter */ 1255 for (i = 0; i < table_entries; i++) { 1256 /* why plus 0x04 ??, That makes the correct value for hash table. */ 1257 outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr); 1258 outl(mc_filter[i], ioaddr + rfdr); 1259 } 1260 1261 outl(RFEN | rx_mode, ioaddr + rfcr); 1262 1263 /* sis900 is capable of looping back packets at MAC level for 1264 * debugging purpose */ 1265 if (net_dev->flags & IFF_LOOPBACK) { 1266 u32 cr_saved; 1267 /* We must disable Tx/Rx before setting loopback mode */ 1268 cr_saved = inl(ioaddr + cr); 1269 outl(cr_saved | TxDIS | RxDIS, ioaddr + cr); 1270 /* enable loopback */ 1271 outl(inl(ioaddr + txcfg) | TxMLB, ioaddr + txcfg); 1272 outl(inl(ioaddr + rxcfg) | RxATX, ioaddr + rxcfg); 1273 /* restore cr */ 1274 outl(cr_saved, ioaddr + cr); 1275 } 1276 1277 return; 1278 } 1279 1280 1281 /* Function: sis900_check_mode 1282 * 1283 * - check the media mode for sis900 1284 * @net_dev: the net device to be checked 1285 * @mii_phy: the mii phy 1286 * 1287 * Older driver gets the media mode from mii status output 1288 * register. Now we set our media capability and auto-negotiate 1289 * to get the upper bound of speed and duplex between two ends. 1290 * If the types of mii phy is HOME, it doesn't need to auto-negotiate 1291 * and autong_complete should be set to 1. 1292 * Returns: void. 1293 */ 1294 1295 static void 1296 sis900_check_mode(struct net_device *net_dev, struct mii_phy *mii_phy) 1297 { 1298 int speed, duplex; 1299 struct sis900_private *sis_priv = net_dev->priv; 1300 long ioaddr = net_dev->base_addr; 1301 1302 if (mii_phy->phy_types == LAN) { 1303 outl(~EXD & inl(ioaddr + cfg), ioaddr + cfg); 1304 sis900_set_capability(net_dev , mii_phy); 1305 sis900_auto_negotiate(net_dev, sis_priv->cur_phy); 1306 } else { 1307 outl(EXD | inl(ioaddr + cfg), ioaddr + cfg); 1308 speed = HW_SPEED_HOME; 1309 duplex = FDX_CAPABLE_HALF_SELECTED; 1310 sis900_set_mode(ioaddr, speed, duplex); 1311 sis_priv->autong_complete = 1; 1312 } 1208 1313 } 1209 1314 … … 1299 1404 } 1300 1405 1406 1301 1407 /** 1302 1408 * sis900_timer - sis900 timer routine … … 1366 1472 } 1367 1473 1368 /**1369 * sis900_check_mode - check the media mode for sis9001370 * @net_dev: the net device to be checked1371 * @mii_phy: the mii phy1372 *1373 * Older driver gets the media mode from mii status output1374 * register. Now we set our media capability and auto-negotiate1375 * to get the upper bound of speed and duplex between two ends.1376 * If the types of mii phy is HOME, it doesn't need to auto-negotiate1377 * and autong_complete should be set to 1.1378 */1379 1380 static void sis900_check_mode(struct net_device *net_dev, struct mii_phy *mii_phy)1381 {1382 struct sis900_private *sis_priv = net_dev->priv;1383 long ioaddr = net_dev->base_addr;1384 int speed, duplex;1385 1386 if (mii_phy->phy_types == LAN) {1387 outl(~EXD & inl(ioaddr + cfg), ioaddr + cfg);1388 sis900_set_capability(net_dev , mii_phy);1389 sis900_auto_negotiate(net_dev, sis_priv->cur_phy);1390 } else {1391 outl(EXD | inl(ioaddr + cfg), ioaddr + cfg);1392 speed = HW_SPEED_HOME;1393 duplex = FDX_CAPABLE_HALF_SELECTED;1394 sis900_set_mode(ioaddr, speed, duplex);1395 sis_priv->autong_complete = 1;1396 }1397 }1398 1474 1399 1475 /** … … 2315 2391 } 2316 2392 2317 /**2318 * set_rx_mode - Set SiS900 receive mode2319 * @net_dev: the net device to be set2320 *2321 * Set SiS900 receive mode for promiscuous, multicast, or broadcast mode.2322 * And set the appropriate multicast filter.2323 * Multicast hash table changes from 128 to 256 bits for 635M/B & 900B0.2324 */2325 2326 static void set_rx_mode(struct net_device *net_dev)2327 {2328 long ioaddr = net_dev->base_addr;2329 struct sis900_private * sis_priv = net_dev->priv;2330 u16 mc_filter[16] = {0}; /* 256/128 bits multicast hash table */2331 int i, table_entries;2332 u32 rx_mode;2333 2334 /* 635 Hash Table entries = 256(2^16) */2335 if((sis_priv->chipset_rev >= SIS635A_900_REV) ||2336 (sis_priv->chipset_rev == SIS900B_900_REV))2337 table_entries = 16;2338 else2339 table_entries = 8;2340 2341 if (net_dev->flags & IFF_PROMISC) {2342 /* Accept any kinds of packets */2343 rx_mode = RFPromiscuous;2344 for (i = 0; i < table_entries; i++)2345 mc_filter[i] = 0xffff;2346 } else if ((net_dev->mc_count > multicast_filter_limit) ||2347 (net_dev->flags & IFF_ALLMULTI)) {2348 /* too many multicast addresses or accept all multicast packet */2349 rx_mode = RFAAB | RFAAM;2350 for (i = 0; i < table_entries; i++)2351 mc_filter[i] = 0xffff;2352 } else {2353 /* Accept Broadcast packet, destination address matchs our2354 * MAC address, use Receive Filter to reject unwanted MCAST2355 * packets */2356 struct dev_mc_list *mclist;2357 rx_mode = RFAAB;2358 for (i = 0, mclist = net_dev->mc_list;2359 mclist && i < net_dev->mc_count;2360 i++, mclist = mclist->next) {2361 unsigned int bit_nr =2362 sis900_mcast_bitnr(mclist->dmi_addr, sis_priv->chipset_rev);2363 mc_filter[bit_nr >> 4] |= (1 << (bit_nr & 0xf));2364 }2365 }2366 2367 /* update Multicast Hash Table in Receive Filter */2368 for (i = 0; i < table_entries; i++) {2369 /* why plus 0x04 ??, That makes the correct value for hash table. */2370 outl((u32)(0x00000004+i) << RFADDR_shift, ioaddr + rfcr);2371 outl(mc_filter[i], ioaddr + rfdr);2372 }2373 2374 outl(RFEN | rx_mode, ioaddr + rfcr);2375 2376 /* sis900 is capable of looping back packets at MAC level for2377 * debugging purpose */2378 if (net_dev->flags & IFF_LOOPBACK) {2379 u32 cr_saved;2380 /* We must disable Tx/Rx before setting loopback mode */2381 cr_saved = inl(ioaddr + cr);2382 outl(cr_saved | TxDIS | RxDIS, ioaddr + cr);2383 /* enable loopback */2384 outl(inl(ioaddr + txcfg) | TxMLB, ioaddr + txcfg);2385 outl(inl(ioaddr + rxcfg) | RxATX, ioaddr + rxcfg);2386 /* restore cr */2387 outl(cr_saved, ioaddr + cr);2388 }2389 2390 return;2391 }2392 2393 2393 2394 2394 /**
Note: See TracChangeset
for help on using the changeset viewer.